将静态链接库转换为动态dll

时间:2010-03-05 06:21:00

标签: dll static visual-c++

我的.lib文件及其标题(.h)文件。该文件有一些需要在C#应用程序中使用的函数。

在谷歌搜索后,我发现我需要从这个静态库创建一个动态DLL,并使用互操作从C#代码调用这个动态DLL。

  1. 我创建了一个win32项目并选择了类型DLL。
  2. 包含头文件并将.lib添加到其他依赖项。

    我能够看到静态库中定义的函数(当我按下ctrl + space时)。

  3. 作为一个新手,我不知道如何导出该函数,即.lib中有以下签名:

    void testfun( char* inp_buff, unsigned short* inp_len, char* buffer_decomp,unsigned *output_len,unsigned short *errorCode)
    

    我想在动态DLL中使用不同名称的相同签名。

    在头文件和.cpp文件中写什么?

6 个答案:

答案 0 :(得分:6)

如果您可以重新编译您的lib,只需将__declspec(dllexport)添加到您要导出的所有功能的签名中。

void __declspec(dllexport) testfun( char* inp_buff, unsigned short* inp_len, char* buffer_decomp,unsigned *output_len,unsigned short *errorCode)

如果你不能这样做,那么你可以通过编写.def文件来导出它们。使用def文件甚至可以在导出时更改函数的名称。 http://msdn.microsoft.com/en-us/library/28d6s79h.aspx

---- mylib.def的内容----

LIBRARY

EXPORTS
   testfun
   newname=testfun2

然后当你链接dll时,请包含mylib.def

link /dll /machine:x86 /def:mylib.def  mylib.lib

EDIT2:

请注意,除非您另有说明,否则pinvoke会假定您导入的函数将具有_stdcall调用约定。因此,您可能需要在C#代码中执行此操作。

[DllImport("mylib.dll", CallingConvention=CallingConvention.Cdecl)]

或者,您可以将C ++代码更改为__stdcall

void __declspec(dllexport) __stdcall testfun( char* inp_buff, ...

答案 1 :(得分:3)

使用Visual Studio应用程序向导创建新的Dll项目,并在其中一个向导步骤中选中“导出符号”。它创建了导出类,函数和变量的样本Dll。您可以从此示例中学习如何执行此操作。 通常,每个导出的函数都声明为__declspec(dllexport)。在客户端项目中,它被声明为__declspec(dllimport)。 Dll代码使用在Dll项目中被玷污为__declspec(dllexport)的常量,在任何其他地方使用__declspec(dllimport)。

答案 2 :(得分:3)

这是你可以做的

  1. 将以下代码添加到.H文件中。将“MYPROJECT”重命名为您的项目名称

    #ifdef MYPROJECT_EXPORTS
    #define MYPROJECT_API __declspec(dllexport)
    #else
    #define MYPROJECT_API _declspec(dllimport)
    #endif
    
  2. 转到属性 - > C ++ - >预处理器并添加防御 - MYPROJECT_EXPORTS

  3. 将MYPROJECT_API添加到您希望dll公开的所有函数中,例如:

    MYPROJECT_API void Test();
    
  4. 转到项目属性常规 - >配置类型将其更改为Dynamic Dll

  5. 你已经完成了

答案 3 :(得分:1)

可以生成两个版本的LIB, 拳头是动态库,(源文件+标题+动态库) - >访问DLL

或static lib =(动态lib + DLL) - > (源文件+标题) - >访问DLL。

如果你有动态Lib>没有办法创建DLL(你无法从中得到任何东西),动态lib只是一个接口,

但是如果你有静态Lib,则不需要DLL来访问它是函数。

答案 4 :(得分:0)

查看我对this question的回答,寻找可能的解决方案。几乎是积极的,这对你有用......

简而言之:在链接器设置中启用“使用库依赖关系输入”选项。如果设置为“true”,它将强制链接所有符号&在每个指定为项目输入的LIB中声明的代码。

答案 5 :(得分:0)

这里的问题不是代码的装饰方式,而是创建包含所有入口点的静态库的额外步骤,并尝试构建其中的dll。

如果你使用__delcspec方法并首先构建静态库,那么在构建DLL时尝试链接到它,你必须解决死代码剥离问题。

当您链接时,obj srcs用于查找所有已修饰的导出和依赖项已解析,其他所有内容都将被删除。如果你没有DLL src,所以没有obj文件(除了dll main之外),你要导出的lib中的所有代码都将被剥离(无论属性如何)。

所以,你要么:

  1. 告诉链接器不要删除未使用的代码,这可能会给你很多你不想要的东西。
  2. 使用def文件手动公开导出
  3. 将dll链接到用于创建lib的obj文件,而不是直接链接到lib。
  4. 或者创建虚拟代码,引用您要从导出的内容导出的函数。