You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows下Julia调用C函数:MinGW正常MSBuild编译失败排查

解决MSBuild编译的64位DLL无法被Julia ccall调用的问题

你碰到的这个问题,本质是MinGW和MSVC(MSBuild背后的编译器)在C函数导出规则、符号处理上的差异导致的,再加上代码里的一个小细节放大了问题,咱们一步步搞定它:

核心问题分析

  1. 函数名大小写与声明不匹配:你的C代码里声明的是int givemin(void);(全小写),但定义的是int giveMin(void)(驼峰式)。MinGW对符号大小写的处理比较宽松,或者编译时自动兼容了这种不一致,但MSVC会严格区分,这就导致MSBuild编译出的DLL里,导出的符号可能是givemin而非你Julia代码里调用的giveMin。
  2. MSVC默认不导出全局函数到DLL:MinGW编译DLL时,默认会导出未被static修饰的全局函数,但MSVC需要显式标记函数为导出符号,否则函数不会被加入DLL的导出表,Julia自然找不到对应的函数。

具体解决方案

第一步:修正C代码的声明与定义一致性

先把函数的声明和定义统一成相同的命名,避免大小写问题:

// 统一使用驼峰命名的声明
int giveMin(void);

int giveMin(void){
 int minval = 0;
 return minval;
}

第二步:让MSVC显式导出函数

有两种简单的方式实现:

方式1:在代码中添加导出标记

通过编译器宏判断,给MSVC编译的代码添加__declspec(dllexport)标记,其他编译器(比如MinGW)不需要:

#ifdef _MSC_VER
// 针对MSVC,标记函数为DLL导出符号
#define EXPORT __declspec(dllexport)
#else
// 其他编译器不需要特殊标记
#define EXPORT
#endif

EXPORT int giveMin(void);

EXPORT int giveMin(void){
 int minval = 0;
 return minval;
}

方式2:使用模块定义文件(.def)

如果不想修改C代码,可以创建一个名为libgetMinimum.def的文件,内容如下:

LIBRARY libgetMinimum
EXPORTS
    giveMin @1

然后在你的CMakeLists.txt中,把这个.def文件关联到目标库:

add_library(libgetMinimum SHARED your_c_source_file.c libgetMinimum.def)

MSBuild会根据这个.def文件,把指定的函数导出到DLL中。

第三步:验证DLL的导出符号

可以用VS自带的dumpbin工具确认函数是否成功导出:
打开Visual Studio的开发者命令提示符,运行以下命令:

dumpbin /exports "C:\MyProjects\Julia-Tests\some-c-lib\build-msvc\src\libgetMinimum.dll"

如果输出结果里能看到giveMin这个符号,说明导出成功,此时再用Julia的ccall调用就不会报错了。

内容的提问来源于stack exchange,提问作者sruli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:08:05