我有一个导出DLL的简单程序,该DLL从另一个DLL导出功能:
// SDK_DLL.cpp :
#include "functions.h"
#include "functions_advanced.h"
#include "stdafx.h"
#include <stdio.h>
using namespace std;
extern "C"
{
__declspec(dllexport) void DisplayHelloFromDLL()
{
printf("Hello from DLL...");
}
__declspec(dllexport) function_config FuncInit = appd_config_init();
__declspec(dllexport) function_config * FuncInit2()
{
function_config* cfg = function_config_init();
return cfg;
}
}
function_config_init()返回一个指针,我似乎找不到找到适当的导出声明的方法。
我正在以这种方式向Delphi加载一个简单的函数:
procedure DisplayHelloFromDLL; external 'C:\Users\Administrator\Documents\Visual Studio 2017\Projects\SDK_DLL\Debug\SDK_DLL.dll';
我是否需要更改加载此指针返回函数的方式?
非常感谢您的帮助。
答案 0 :(得分:2)
FuncInit
是导出的变量。 Delphi不支持通过external
导入变量,仅支持函数。如果您需要导入FuncInit
,则必须直接使用GetProcAddress()
在运行时获取指向变量的指针:
type
// you did not show the C/C++ declaration
// of function_config, so I can't provide
// a translation here, but it is likely to
// be a struct, which is a record in Delphi ...
function_config = ...;
pfunction_config = ^function_config;
function GetFuncInit: pfunction_config;
begin
Result := pfunction_config(GetProcAddress(GetModuleHandle('SDK_DLL.dll'), 'FuncInit'));
end;
var
FuncInit: pfunction_config;
FuncInit := GetFuncInit;
出于跨语言/编译器互操作的目的,唯一的可移植调用约定为cdecl
和stdcall
。当代码中未指定调用约定时,大多数C和C ++编译器使用的默认设置为__cdecl
(但通常可以在编译器设置中指定),而Delphi使用的默认设置为register
({{ C ++ Builder中的{1}}。
如__fastcall
中未使用任何参数或返回值时,则声明错误的调用约定并不重要。但是,当使用参数和/或返回值时(例如在DisplayHelloFromDLL()
中),则声明正确的调用约定很重要。有关更多详细信息,请参见Pitfalls of converting。
因此,可能需要像在Delphi中那样声明两个有问题的DLL函数:
FuncInit2()
如果DLL使用type
function_config = ...;
pfunction_config = ^function_config;
procedure DisplayHelloFromDLL; cdecl; external 'SDK_DLL.dll' name '_DisplayHelloFromDLL';
function FuncInit2: pfunction_config; cdecl; external 'SDK_DLL.dll' name '_FuncInit2';
文件从导出的名称中删除名称修饰,则可以省略.def
属性:
name