我对C++和使用DLL相当陌生。 我有一个主要的应用程序,它聚合来自不同测量的结果。 由于不同情况下的度量不同,我决定将它们放入外部DLL中,以便在运行时加载它们(它们只是导出相同的函数)。 这样就可以根据运行时的需要扩展聚合器:
typedef int (*measure)(measurement &dataHolder);
int callM() {
[...]
measurement dataHolder;
lib = LoadLibraryA("measureDeviceTypeA.dll");
measure measureFunc = (measure)GetProcAddress(lib, "measureFunc");
pluginFunc(dataHolder);
[...] // close the lib and load the next one depending on found Devices
}
这对于简单的数据类型(取决于结构“measurement”的实际定义)非常有效,如下所示:
typedef struct measurement {
DWORD realPBS;
DWORD imaginaryPBS;
int a;
} measurement;
现在还可能有一个任意长度的字符串(结果的char表示)。 我也想把它们放入度量结构中,并将它们填充到DLL中的实际工作者函数中。 我的第一个假设是,只使用std::string会很容易,它有时起作用,有时不起作用(因为它会在std::string().append()
上重新分配内存,这可能会中断(访问冲突),具体取决于程序和dll的实际运行时环境)。 我在这里和这里读到,从函数返回字符串是个坏主意。
那么从这样的调用中返回任意长度字符串的“正确”C++方式是什么呢? 将一个结构传递给DLL有帮助吗?还是我应该将它拆分成几个单独的调用? 当我再次关闭DLL时,我不想让指针晃来晃去或内存未释放。
正如Dani在注释中指出的那样,这对std::string
不起作用。 问题是std::string
是属于您的实现的类型,不同的C++实现具有不同的std::string
。
对于DLL的具体(Microsoft),您确实有另一种选择。 COM是一项古老的技术,但它至今仍然有效,而且不太可能永远消失。 并且它有自己的字符串类型bstr
。 Visual Studio为您自己的代码提供了一个辅助C++类bstr_t
,但在界面上您将使用_bstr_t::getbstr
中的纯bstr
。
bstr
依赖于oleaut32.dll
中的Windows分配器sysallocstring