1.80雪山飞狐合击:如何创建动态链接库?

来源:百度文库 编辑:高考问答 时间:2024/05/10 18:38:05
我知道如何用汇编创建dll,
请问如何将C++函数创建为dll动态链接库?
再弱弱的问一句java写的函数可以生成动态链接库吗?
还有一个小问题,.dll动态链接库无论是什么语言写的,都可以被任何语言的Windows程序调用吗?
专家龙车花卉的答案仅说了dll在调用时的函数名字问题啊……而且选择的答案是翻译的文章,比较生涩。我急需知道的是比如我有一些C++的函数代码,而我希望能生成.dll供Java程序(或C++程序)调用,如何操作?

有专门软件,一般在编译器中自带有导出工具。

先回答最后一个问题: .DLL的限制是很大的, 不同的语言(或叫编程工具)所做出来的DLL, 一般来说WINDOWS调用都有困难

下面给你说一下VC++做通用一点的DLL

创建用于非VisualC++工具的DLL

如果使用MicrosoftVisualC++来创建DLL和将要链接到该DLL的可执行模块,可以跳过本节内容的学习。但是,如果使用VisualC++创建DLL,而这个DLL要链接到使用任何供应商的工具创建的可执行模块,那么必须做一些额外的工作。

前面讲过当进行C和C++混合编程时使用extern“C”修改符的问题。也讲过C++类的问题以及为什么因为名字改变的缘故你必须使用同一个编译器供应商的工具的问题。当你直接将C语言编程用于多个工具供应商时将会出现另一个问题。这个问题是,即使你根本不使用C++,Microsoft的C编译器也会损害C函数。当你的函数使用__stdcall(WINAPI)调用规则时会出现这种问题。这种调用规则是最流行的一种类型。当使用__stdcall将C函数输出时,Microsoft的编译器就会改变函数的名字,设置一个前导下划线,再加上一个@符号的前缀,后随一个数字,表示作为参数传递给函数的字节数。例如,下面的函数是作为DLL的输出节中的_MyFunc@8输出的:

_declspec(dllexport) LONG _stdcall MyFunc(int a, int b);

如果用另一个供应商的工具创建了一个可执行模块,它将设法链接到一个名叫MyFunc的函数,该函数在Microsoft编译器已有的DLL中并不存在,因此链接将失败。

若要使用与其他编译器供应商的工具链接的Microsoft的工具创建一个可执行模块,必须告诉Microsoft的编译器输出没有经过改变的函数名。可以用两种方法来进行这项操作。第一种方法是为编程项目建立一个.def文件,并在该.def文件中加上类似下面的EXPORTS节:

EXPORTS

MyFunc

当Microsoft的链接程序分析这个.def文件时,它发现_MyFunc@8和MyFunc均被输出。由于这两个函数名是互相匹配的(除了截断的尾部外),因此链接程序使用MyFunc的.def文件名来输出该函数,而根本不使用_MyFunc@8的名字来输出函数。

现在你可能认为,如果使用Microsoft的工具创建一个可执行模块,并且设法将它链接到包含未截断名字的DLL,那么链接程序的运行将会失败,因为它将试图链接到称为_MyFunc@8的函数。当然,你会高兴地了解到Microsoft的链接程序进行了正确的操作,将可执行模块链接到名字为MyFunc的函数。

如果想避免使用.def文件,可以使用第二种方法输出未截断的函数版本。在DLL的源代码模块中,可以添加下面这行代码:

#pragma comment(linker , "/export:MyFunc = _MyFunc@8")

这行代码使得编译器发出一个链接程序指令,告诉链接程序,一个名叫MyFunc的函数将被输出,其进入点与称为_MyFunc@8的函数的进入点相同。第二种方法没有第一种方法容易,因为你必须自己截断函数名,以便创建该代码行。另外,当使用第二种方法时,DLL实际上输出用于标识单个函数的两个符号,即MyFunc和_MyFunc@8,而第一种方法只输出符号MyFunc。第二种方法并没有给你带来更多的好处,它只是使你可以避免使用.def的文件而已。