You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何静态链接仅按序号导出的DLL函数?(Visual Studio环境)

如何在Visual Studio C++中通过序号静态链接DLL导出函数

刚好之前折腾过VS下按序号静态链接仅导出序号的DLL函数的需求,给你分享两种实用的方法,一步步就能搞定:

方法一:自定义.def文件生成导入库

因为目标DLL只通过序号1导出TestFunc01,我们需要手动创建一个.def文件来帮链接器建立“函数名-序号”的映射,具体步骤:

  1. 新建一个.def文件(比如命名为MyImport.def),写入以下内容:
LIBRARY DllName
EXPORTS
TestFunc01 @1

这里不要加原DLL.def里的NONAME,我们需要给这个序号绑定一个名字,方便自己的代码调用。
2. 生成导入库:打开Visual Studio的开发者命令提示符,执行lib.exe命令(根据你的项目位数选择参数):

# 32位项目
lib /def:MyImport.def /out:MyImport.lib /machine:x86

# 64位项目
lib /def:MyImport.def /out:MyImport.lib /machine:x64
  1. 在你的C++项目中,把生成的MyImport.lib添加到项目属性→链接器→输入→附加依赖项里,然后代码里就可以正常使用原函数声明调用了:
extern "C" __declspec(dllimport) int TestFunc01(int v);

int _tmain(int argc, _TCHAR* argv[]) {
    TestFunc01(123);
}

方法二:直接在代码中使用链接器指令(无需额外生成导入库)

这种方法更轻量化,不用手动生成导入库,直接通过#pragma comment给链接器传递指令,绑定函数到指定序号:
你可以直接用原函数名,代码更直观:

// 声明导入函数
extern "C" __declspec(dllimport) int TestFunc01(int v);

// 告诉链接器:这个TestFunc01对应DllName.dll中的序号1
#pragma comment(linker, "/export:TestFunc01=DllName.#1")

int _tmain(int argc, _TCHAR* argv[]) {
    TestFunc01(123);
}

或者也可以自定义函数名(比如TestFuncByOrdinal),只要链接器指令里对应好就行:

extern "C" __declspec(dllimport) int TestFuncByOrdinal(int v);
#pragma comment(linker, "/export:TestFuncByOrdinal=DllName.#1")

int _tmain(int argc, _TCHAR* argv[]) {
    TestFuncByOrdinal(123);
}

这里的#1就是指定目标函数的导出序号,DllName是你要链接的DLL文件名(不用加.dll后缀)。

注意事项

  • 不管用哪种方法,都要确保DllName.dll在程序运行时能被找到(比如放到项目输出目录或者系统PATH路径下)
  • 如果你用的是64位项目,执行lib.exe时一定要指定/machine:x64,32位项目对应x86,否则生成的导入库会和项目位数不匹配
  • 链接器指令里的DLL名字不区分大小写,但尽量和实际DLL文件名保持一致,避免不必要的问题

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

火山引擎 最新活动