c++ - 用 C/C++ 编译 DLL,然后从另一个程序调用它

标签 c++ c gcc vb6 mingw

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

制作一个导出一些函数的 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++)程序中,然后从中调用这些函数。 在玩了一会儿 DLL 之后,我的目标是通过将 DLL 加载到 Visual Basic 中,为 C(++) 代码创建一个 VB 前端(我有 Visual Studio 6,我只想制作一些表单和这些窗体上的对象的事件(调用 DLL)。

我需要知道如何调用 gcc (/g++) 以使其创建 DLL,还需要知道如何编写(/生成)导出文件...以及我可以/不能在 DLL 中做什么(例如,我可以从 VB 前端通过指针/引用获取参数吗?DLL 可以在前端调用理论函数吗?或者让一个函数从 VB 获取一个“函数指针”(我什至不知道这是否可能) VB 并调用它?)我相当确定我无法将变体传递给 DLL...但这就是我所知道的全部。

再次更新

好吧,我想出了如何用 gcc 编译它,以生成我运行的 dll

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

然后我让另一个程序加载它并测试功能,效果很好, 十分感谢您的建议, 但我尝试用 VB6 加载它,就像这样

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.");
  }

}

有什么想法吗?

解决了

为了解决前面的问题,我只需像这样编译它:

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 是否确实导出了函数,请获取免费的 Dependency Walker工具并用它来检查 DLL。

对于一个可以自动执行构建 DLL 所需的所有标志等的免费 IDE,请查看优秀的 Code::Blocks ,它与 MinGW 配合得很好。

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

关于c++ - 用 C/C++ 编译 DLL,然后从另一个程序调用它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57795786/

相关文章:

c++ - 多重延续链接 : boost. future 展开。怎么做

c - strsep() 用法及其替代方法

c - 如何释放对齐指针?

c - 基本的 C 问题 - 当你在 C 中声明一个静态变量时到底发生了什么?

c++ - cppcheck 在模板中使用时提示 unreadVariable

c++ - 这段代码是如何工作的?

linux - gsl : make file not linking,/usr/bin/ld: 找不到-lgsl

c++ - Winelib - 控制台应用程序

c - Tint2 编译

c++ - Qt GUI 应用程序可以在我的电脑上运行,但不能在另一台电脑上运行?