我正在编写一个C / C ++ DLL,想要在使用像这样的.def文件之前导出我已经完成的某些功能

LIBRARY "MyLib"
EXPORTS
  Foo
  Bar

使用定义为此的代码,例如:

int Foo(int a);
void Bar(int foo);

但是,如果我想声明一个Foo()的重载方法,如下所示:

int Foo(int a, int b);

由于def文件只有函数名而不是完整的原型,我无法看到它如何处理重载函数。 您是否只使用一个条目,然后在将正确的原型函数指针传递给LoadLibrary()时指定您想要的重载版本?

编辑:要清楚,这是在使用Visual Studio 2005的Windows上

编辑:将非def(__ declspec)方法标记为答案...我知道这实际上并没有像我想的那样使用def文件解决问题,但似乎很可能没有使用def文件的(官方)解决方案。 但是,如果有人知道我们没有重载函数和def文件,我们会将问题保持打开状态。

===============>>#1 票数:11

函数重载是一种C ++特性,它依赖于名称修改(链接器错误消息中的神秘函数名称)。

通过将损坏的名称写入def文件,我可以将我的测试项目链接并运行:

LIBRARY "TestDLL"
EXPORTS
    ?Foo@@YAXH@Z
    ?Foo@@YAXHH@Z

似乎有用

void Foo( int x );
void Foo( int x, int y );

因此,从错误消息中复制C ++函数名称并将其写入def文件。 但是,真正的问题是:为什么要使用def文件而不是__declspec(dllexport)?

受损的名称是不可移植的,我使用VC ++ 2008进行了测试。

===============>>#2 票数:9 已采纳

在代码本身中,使用__declspec(dllexport)标记要导出的函数。 例如:

#define DllExport __declspec(dllexport)

int DllExport  Foo( int a ) {
  // implementation
}
int DllExport Foo( int a, int b ) {
  // implementation
}

如果执行此操作,则无需在.def文件中列出这些函数。

或者,您可以使用默认参数值,例如:

int Foo( int a, int b = -1 )

这假定存在一个b值,可用于指示它未使用。 如果-1是b的合法值,或者如果没有或不应该是默认值,则这将不起作用。

编辑(Adam Haile):更正使用__declspec作为__dllspec不正确所以我可以将其标记为正式答案......它足够接近。

编辑(格雷姆):哎呀 - 感谢纠正我的错字!

===============>>#3 票数:8

我有类似的问题,所以我也希望发布这个问题。

  1. 通常使用

     extern "C" __declspec(dllexport) void Foo(); 

    导出函数名称很好。 通常会输出名称unmangled而不需要.def文件。 但是,有一些例外,例如__stdcall函数和重载函数名。

  2. 如果声明一个函数使用__stdcall约定(就像许多API函数一样)那么

     extern "C" __declspec(dllexport) void __stdcall Foo(); 

    将导出像_Foo @ 4这样的错位名称。 在这种情况下,您可能需要将导出的名称显式映射到内部损坏的名称。

A.如何导出未编码的名称。 在.def文件中添加

----
EXPORTS
    ; Explicit exports can go here

    Foo
-----

这将尝试为内部函数Foo找到“最佳匹配”并将其导出。 在上面只有一个foo的情况下,这将创建映射

Foo = _Foo @ 4

通过dumpbin / EXPORTS可以看到

如果您重载了一个函数名,那么您可能需要通过使用entryname [= internalname]语法指定一个受损的名称来明确说明.def文件中您想要的函数。 例如

----
EXPORTS
    ; Explicit exports can go here

    Foo=_Foo@4
-----

B. .ff文件的替代方法是您可以使用#pragma“就地”导出名称。

#pragma comment(linker, "/export:Foo=_Foo@4")

C.第三种方法是声明只有一个版本的Foo作为外部“C”来导出未编译的。 详情请见此处

===============>>#4 票数:3

没有正式的方法可以做你想要的,因为dll接口是一个C api。

编译器本身使用损坏的名称作为变通方法,因此当您不希望在代码中进行太多更改时,应使用名称修改。

===============>>#5 票数:2

EXPORTS定义的Systax是:

entryname[=internalname] [@ordinal [NONAME]] [PRIVATE] [DATA]

entryname是要导出的函数或变量名称。 这是必需的。 如果导出的名称与DLL中的名称不同,请在DLL中使用internalname指定导出的名称。

例如,如果您的DLL导出函数func1()并且您希望将其用作func2(),则应指定:

EXPORTS
func2=func1

只需查看损坏的名称(使用Dependency walker)并指定您自己的函数名称。

资料来源: http//msdn.microsoft.com/en-us/library/hyx1zcd3(v = vs.71).aspx

编辑:这适用于动态DLL,我们需要使用GetProcAddress()显式获取Dll中的函数。

===============>>#6 票数:2

由于修改约定随编译器的每个版本而变化,因此没有一种语言或版本无关的导出重载函数的方法。

这就是为什么大多数WinXX函数都有像* Ex或* 2这样有趣的名字的原因之一。

  ask by Adam Haile translate from so

未解决问题?本站智能推荐:

6回复

.def文件C / C ++ DLL

我不了解将.def文件与DLL一起使用的意义。 似乎它取代了在DLL代码中使用显式导出的需求(即,显式__declspec(dllexport)),但是当我不使用这些文件时,我无法生成lib文件,而在以后使用DLL时,它会产生链接器问题。 那么在与客户端应用程序链接时如何使用.def
1回复

从C DLL调用重载的C ++函数

有一个用MSVC C ++编写的应用程序(Proteus VSM),它支持基于DLL的插件。 由g ++(mingw32)生成的DLL与MSVC不兼容,__thiscall和其他方式没有帮助。我的大部分代码是用gcc / mingw编写的,并且有很多基于GAS的汇编部件(不用于加速)等,因
1回复

C ++和MQL4在dll中找不到函数

好吧,我知道每个人都在想:“这已经被回答了好几次了。” 好吧,你错了。 这次不一样了。 我已经尝试了所有其他答案。 情况就是这样。 我正在Metatrader 4(mql4代码)中创建指标。 我正在编码一个dll以在C ++中的Visual Studio 2013中进行计算。
1回复

DLL中C样式函数中的静态变量

像这样在DLL中存在一个函数: 该静态对象将在内存中位于何处? 如果从多个其他DLL调用此函数,是否将存在此静态对象的多个副本?
1回复

在C ++中导入dll函数

我有一个名为swedll32.dll的Dll文件,该文件用于天文计算。 我已经在C#中导入了这些函数并正在使用它们。 但是在C ++中,我尝试了所有可能的方法来导入这些函数,但是它不起作用。 请问有人演示如何导入具有给定名称的函数吗? int swe_calc_ut(double
2回复

C程序中的C ++ dll

我想用C ++代码创建一个dll库,并在C程序中使用它。 我只想导出一个函数: 来自库的头文件: 在.cpp(在库项目中)函数也声明为: 文件.lib添加在VS项目选项(链接器/输入/附加依赖项)中。 .dll位于.exe所在的文件夹中。 当我编译C项目时 - 错误
1回复

使用dll源代码C ++调试dll文件

我在带有QMake构建系统的MS-Windows中将QtCreator IDE与MSVC2017一起使用。 为了概括我的调试问题,我将举一个例子: 我使用以下文件创建一个名为library的项目: 库.h 库 我从我的library项目中制作了.dll和.lib 。
2回复

DLL入口点函数中的函数声明C ++中的WINAPI标识符

这个问题已经在这里有了答案: 主要功能中的“ WINAPI”是什么意思? 4个答案 定义调用约定有什么意义? 5个答案 我正在学习如何使用C ++创建dll 。 出现以下内容: 而且我不明白DllMain() "WINAPI"是什么?
4回复

将C DLL的函数导入C ++程序

我有一个用C语言编写的第三方库。它将所有函数导出到DLL。 我有.h文件,我正在尝试从我的C ++程序加载DLL。 我尝试的第一件事是围绕我#include第三方lib的部分 最后 但问题是,所有的DLL文件功能链接在它们的头文件中看起来像这样: 虽然a_fu
1回复

在dll中导出函数。 C和C ++

我有一个名为ProCharts的应用程序,可以从C ++ dll中读取和访问文件。 现在,如果我添加类似的内容并以x64模式编译dll。(VS2010-> Win32控制台应用程序-> DLL) 然后在def文件中对其进行定义。可以从该应用程序正常调用该函数。 但是,