如何在 dll 中编写函数体,但在我的主程序中有原型
How do I write the body of a function in a dll, but have the prototype in my main program
抱歉,如果问题很初级,我是 .dll-s 的新手。基本上我想让我的函数访问它在最初定义的主程序中所做的相同的全局变量,而实际上是在 .dll
中编写的
示例:我有一个 ListView 对象,我正在从函数中打印消息
void example(){
//Display is my listview
Display->Items->Add("Hello world");
}
在此示例中,Display 是一个 TListView 对象,它在我的 main.cpp 中初始化,我从中定义了我的 VCL 应用程序表单的行为。这个 Display 对象是主 cpp 中的一个全局变量,因此当我剪切 example() 并将其粘贴到我的新 dll 中时它会中断,因为在 dll 的范围内 Display 不存在。
我的想法是声明函数原型void example();在 main.h 中,以某种方式在我的 dll 中写入正文,但是当我将 <"anything"> 包含到 dll 中时,编译器会尖叫说我不知道我正在尝试做什么...
我有哪些选择?
我正在使用 C++ 生成器,但我认为同样的逻辑问题将适用于任何 IDE
你完全错了。 DLL 无法访问它外部的变量,就像在主 EXE 中一样,除非外部代码将 DLL pointers/references 提供给它们。在您提供的示例中,这对您没有任何帮助。
更好的设计是完全不让 DLL 直接访问变量。在您的示例中,您应该让 EXE 将指向 回调函数 的指针传递给 DLL,然后 DLL 可以在需要时调用它。在内部,该函数可以根据需要使用 EXE 的变量。
例如:
MyDLL.h
#ifndef MyDLL_H
#define MyDLL_H
#ifdef BUILDING_DLL
#define MY_API __declspec(dllexport)
#else
#define MY_API __declspec(dllimport)
#endif
typedef void (__stdcall *myTextCallback)(const char *text, void *userData);
MY_API void __stdcall dll_setTextCallback(myTextCallback userCallback, void *userData);
#endif
MyDll.cpp
#define BUILDING_DLL
#include "MyDll.h"
myTextCallback textCallback = NULL;
void *textCallbackData = NULL;
void __stdcall dll_setTextCallback(myTextCallback userCallback, void *userData)
{
textCallback = userCallback;
textCallbackData = userData;
}
void doSomething()
{
...
if (textCallback)
textCallback("Hello World", textCallbackData);
...
}
EXE
#include "MyDll.h"
void __stdcall displayText(const char *text, void *userData)
{
TListItem *Item = static_cast<TMainForm*>(userData)->Display->Items->Add();
Item->Caption = text;
}
__fastcall TMainForm::TMainForm(TComponent *Owner)
: TForm(Owner)
{
dll_setTextCallback(&displayText, this);
}
__fastcall TMainForm::~TMainForm()
{
dll_setTextCallback(NULL, NULL);
}
这样,DLL 就不必知道或关心 EXE 想要对 DLL 的数据做什么。
抱歉,如果问题很初级,我是 .dll-s 的新手。基本上我想让我的函数访问它在最初定义的主程序中所做的相同的全局变量,而实际上是在 .dll
中编写的示例:我有一个 ListView 对象,我正在从函数中打印消息
void example(){
//Display is my listview
Display->Items->Add("Hello world");
}
在此示例中,Display 是一个 TListView 对象,它在我的 main.cpp 中初始化,我从中定义了我的 VCL 应用程序表单的行为。这个 Display 对象是主 cpp 中的一个全局变量,因此当我剪切 example() 并将其粘贴到我的新 dll 中时它会中断,因为在 dll 的范围内 Display 不存在。
我的想法是声明函数原型void example();在 main.h 中,以某种方式在我的 dll 中写入正文,但是当我将 <"anything"> 包含到 dll 中时,编译器会尖叫说我不知道我正在尝试做什么...
我有哪些选择?
我正在使用 C++ 生成器,但我认为同样的逻辑问题将适用于任何 IDE
你完全错了。 DLL 无法访问它外部的变量,就像在主 EXE 中一样,除非外部代码将 DLL pointers/references 提供给它们。在您提供的示例中,这对您没有任何帮助。
更好的设计是完全不让 DLL 直接访问变量。在您的示例中,您应该让 EXE 将指向 回调函数 的指针传递给 DLL,然后 DLL 可以在需要时调用它。在内部,该函数可以根据需要使用 EXE 的变量。
例如:
MyDLL.h
#ifndef MyDLL_H
#define MyDLL_H
#ifdef BUILDING_DLL
#define MY_API __declspec(dllexport)
#else
#define MY_API __declspec(dllimport)
#endif
typedef void (__stdcall *myTextCallback)(const char *text, void *userData);
MY_API void __stdcall dll_setTextCallback(myTextCallback userCallback, void *userData);
#endif
MyDll.cpp
#define BUILDING_DLL
#include "MyDll.h"
myTextCallback textCallback = NULL;
void *textCallbackData = NULL;
void __stdcall dll_setTextCallback(myTextCallback userCallback, void *userData)
{
textCallback = userCallback;
textCallbackData = userData;
}
void doSomething()
{
...
if (textCallback)
textCallback("Hello World", textCallbackData);
...
}
EXE
#include "MyDll.h"
void __stdcall displayText(const char *text, void *userData)
{
TListItem *Item = static_cast<TMainForm*>(userData)->Display->Items->Add();
Item->Caption = text;
}
__fastcall TMainForm::TMainForm(TComponent *Owner)
: TForm(Owner)
{
dll_setTextCallback(&displayText, this);
}
__fastcall TMainForm::~TMainForm()
{
dll_setTextCallback(NULL, NULL);
}
这样,DLL 就不必知道或关心 EXE 想要对 DLL 的数据做什么。