< 返回版块

eweca-d 发表于 2024-04-27 20:18

由于某个工业软件需要intel fortran(f77)的obj文件来链接来复写旧有功能,但是f77非常之难用。故而有C++与其链接的方法。 makefile如下:

	ifort -O2 -c cpp_ulib.for
	cl -O2 -c mul.cpp
	lib /OUT:ulib.obj cpp_ulib.obj mul.obj

C++代码如下:

extern "C"
void CPP_MUL(double* a, double* b, double* c)
{
    *c = *a * *b;
}

可以正常运行。 但是假使使用rust,根据google的结果我这么写

	ifort -O2 -c rust_ulib.for
	lib /OUT:ulib2.obj rust_ulib.obj rust_mul.o

rust代码如下

#[no_mangle]
pub extern "C" fn RUST_MUL(a: *mut f64, b: *mut f64, c: *mut f64)
{
    unsafe
    {
        *c = (*a) * (*b);
    }
}

使用命令rustc --crate-type=staticlib --print native-static-libs --emit=obj -C panic=abort src/lib.rs -o rust_mul.o来编译rust代码。

但是使用后就会出现

ulib2.obj(rust_mul.o) : error LNK2019: 无法解析的外部符号 _ZN4core9panicking36panic_misaligned_pointer_dereference17hc2b28480d944fa75E,函数 RUST_MUL 中引用了该符号
standardU.dll : fatal error LNK1120: 1 个无法解析的外部命令

请问有什么解决方法吗?看起来像是rust引用了什么奇怪的?另外,假使我直接build一个lib文件进行链接,无法解析的外部符号还更多好几次(但是和这个不一样)。

求教会混编的大佬,虽说也是会C++而且C++写起来应该也挺方便,就是想知道rust能解决这个问题不?

--------------------------------------update

又试了次lib,这次成了。。。

	ifort -O2 -c rust_ulib.for
	lib /OUT:ulib2.obj rust_ulib.obj rust_mul.lib

这次就是正常的cargo release,然后使用生成的C静态库,除了obj真的很大之外,就这么一个乘法10M,其他没啥问题。。。。

评论区

写评论
作者 eweca-d 2024-04-27 23:54

大佬太牛了,可行!重点就是opt-level=3。话说现在加了这个之后,效率应该也是等同于cargo --release了吧?这样的话,效率和尺寸都上去了!

--
👇
TinusgragLin: 好像就算不用 no_std,只加个 opt-level=3 也可以......看来编译器优化可以把不用的符号定义去掉?

TinusgragLin 2024-04-27 22:38

好像就算不用 no_std,只加个 opt-level=3 也可以......看来编译器优化可以把不用的符号定义去掉?

TinusgragLin 2024-04-27 22:25

我试了一下 no_std:

#![no_std]

use core::panic::PanicInfo;
#[panic_handler]
fn panic_handler(_info: &PanicInfo<'_>) -> ! {
    loop {}
}

#[no_mangle]
pub unsafe extern "C" fn RUST_MUL(a: *mut f64, b: *mut f64, c: *mut f64)
{
    *c = (*a) * (*b);
}

rustc --crate-type=staticlib --emit obj -C panic=abort -C opt_level=3 src/lib.rs -o rust_mul.o 编译后,用这个测试的c程序(不熟悉 fortran,抱歉):

#include <stdio.h>

extern void RUST_MUL(double *a, double *b, double *c);
int main() {
    double a = 8, b = 12, c = 0;
    RUST_MUL(&a, &b, &c);
    printf("%f", c);
    return 0;
}

好像通过了 gcc -o test test.c rust_mul.o 编译,运行的结果好像也没问题。楼主可以试一下?

1 共 3 条评论, 1 页