我想制作一个简单的DLL,导出一个或两个函数,然后try 从另一个程序调用它...到目前为止,我所看到的每一个地方,都是复杂的事情,不同的连接方式,奇怪的问题,我甚至还没有意识到这些问题的存在...我只是想开始,通过这样做:

制作一个DLL,导出一些函数,比如,

int add2(int num){
   return num + 2;
}

int mult(int num1, int num2){
   int product;
   product = num1 * num2;
   return product;
}

我正在用MinGW编译,我想用C语言来做这件事,但是如果用C++做这件事有什么真正的不同之处,我也想知道.我想知道如何将该DLL加载到另一个C(和C++)程序中,然后从其中调用这些函数. 在try 了一会儿DLL之后,我在这里的目标是通过将DLL加载到Visual Basic中,为C(++)代码创建一个VB前端(我有Visual Studio6,我只想为这些窗体上的对象制作一些窗体和事件,它们调用DLL).

我需要知道如何调用gcc(/g++)来创建DLL,还需要知道如何编写(/generate)导出文件...以及我在DLL中能做什么/不能做什么(比如,我能从VB前端通过指针/引用获取参数吗?DLL能在前端调用理论函数吗?或者让函数从VB获取"函数指针"(我甚至不知道这是否可能)并调用它?)我很确定我不能将变量传递给DLL...但我真的只知道这些.

再次更新

好吧,我想出了如何用gcc编译它,来制作我运行的dll

gcc -c -DBUILD_DLL dll.c
gcc -shared -o mydll.dll dll.o -Wl,--out-implib,libmessage.a

然后我让另一个程序加载并测试功能,效果很好,

Public Declare Function add2 Lib "C:\c\dll\mydll.dll" (num As Integer) As Integer

然后我刚从表单中调用了add2(text1.text),但它给了我一个运行时错误:

"在C:\C\DLL\mydll.DLL中找不到DLL入口点add2"

以下是我为DLL编译的代码:

#ifdef BUILD_DLL
#define EXPORT __declspec(dllexport)
#else
#define EXPORT __declspec(dllimport)
#endif

EXPORT int __stdcall add2(int num){
  return num + 2;
}

EXPORT int __stdcall mul(int num1, int num2){
  return num1 * num2;
}

这样从C程序调用它是可行的,不过:

#include<stdio.h>
#include<windows.h>

int main(){

  HANDLE ldll;
  int (*add2)(int);
  int (*mul)(int,int);

  ldll = LoadLibrary("mydll.dll");
  if(ldll>(void*)HINSTANCE_ERROR){
    add2 = GetProcAddress(ldll, "add2");
    mul = GetProcAddress(ldll, "mul");
    printf("add2(3): %d\nmul(4,5): %d", add2(3), mul(4,5));
  } else {
    printf("ERROR.");
  }

}

有什么 idea 吗?

解决了

要解决前面的问题,我只需这样编译:

gcc -c -DBUILD_DLL dll.c
gcc -shared -o mydll.dll dll.o -Wl,--add-stdcall-alias

并在VB6中使用此API调用

Public Declare Function add2 Lib "C:\c\dll\mydll" _
    (ByVal num As Integer) As Integer

我学会了不要忘记显式地指定ByVal或ByRef--我只是在取回我传递的参数的地址,它看起来像-3048.

推荐答案

关于使用MinGW构建DLL,下面是一些非常简短的说明.

首先,需要将函数标记为导出,以便DLL的调用者可以使用它们.为此,请修改它们,使其看起来像(例如)

__declspec( dllexport ) int add2(int num){
   return num + 2;
}

然后,假设您的函数位于名为funcs.c的文件中,则可以编译它们:

gcc -shared -o mylib.dll funcs.c

-shared标志告诉gcc创建一个DLL.

要判断DLL是否实际导出了函数,请使用free Dependency Walker工具判断DLL.

对于一个将自动生成DLL所需的所有标志等的免费IDE,请看一看优秀的Code::Blocks,它与MinGW配合得非常好.

Edit:有关此主题的更多详细信息,请参阅MinGW Wiki上的文章Creating a MinGW DLL for Use with Visual Basic.

C++相关问答推荐

为什么复合文字(C99)的返回会生成更多的汇编代码?

从组播组地址了解收到的数据包长度

C:二进制搜索和二进制插入

C:fopen是如何实现二进制模式和文本模式的?

变量>;-1如何在C中准确求值?

双指针指向常量双指针的指针类型赋值不兼容

调用mProtection将堆栈上的内存设置为只读,直接导致程序SIGSEGV

无法在OpenGL上绘制三角形

在C++中允许使用字符作为宏参数

C11/C17标准允许编译器清除复合文字内存吗?

OSDev--双缓冲重启系统

如何将大写/小写土耳其字母相互转换?

从不兼容的指针类型返回&&警告,但我看不出原因

使用mmap为N整数分配内存

生成的头文件不包括用户定义的文件

如何编写postgresql支持函数

为什么GCC不能在 struct 初始值设定项中以sizeof作为条件的三进制中处理复合文字的编译时求值?

浮点正零何时不全为零?

是否可以在多字 C 类型中的任何位置混合存储和类型限定符?

如何使用 raylib 显示数组中的图像