在delphi中使用C-dll不返回任何内容
基于此,我一直在尝试在delphi中重用C dll文件 服务器运行良好,我可以访问并使用本地服务器上的数据库 java和php 在delphi上,我使用动态加载,在所有返回变量的函数上都工作得很好,但在返回接口的函数上却失败了在delphi中使用C-dll不返回任何内容,delphi,dll,dllimport,Delphi,Dll,Dllimport,基于此,我一直在尝试在delphi中重用C dll文件 服务器运行良好,我可以访问并使用本地服务器上的数据库 java和php 在delphi上,我使用动态加载,在所有返回变量的函数上都工作得很好,但在返回接口的函数上却失败了 unit for library : unit SQLDBC_C; interface uses windows, classes, sysutils; type SQLDBC_IRuntime = interface end; var getSDKVe
unit for library :
unit SQLDBC_C;
interface
uses windows, classes, sysutils;
type
SQLDBC_IRuntime = interface
end;
var
getSDKVersion : function :Pchar; stdcall;
ClientRuntime_GetClientRuntime: function (errorText:Pchar; errorTextSize:Integer) : SQLDBC_IRuntime; stdcall;
implementation
var
libhandle : THandle;
procedure initLibrary;
begin
libhandle := LoadLibrary('libSQLDBC_C.dll');
if libhandle>=23 then begin
@getSDKVersion:=GetProcAddress(libhandle,'getSDKVersion');
@ClientRuntime_GetClientRuntime:=
GetProcAddress(libhandle,'ClientRuntime_GetClientRuntime');
end;
end;
initialization
begin
initLibrary;
end;
finalization
begin
if libhandle>=32 then
FreeLibrary(libhandle);
end;
end.
以下是测试程序:
procedure TForm1.Button1Click(Sender: TObject);
var
err : array [0..200] of char;
rt : SQLDBC_IRuntime;
begin
Memo1.Clear;
FillChar(err, sizeof(err), 0);
Memo1.Lines.Add(getSDKVersion); //this function successed
rt := ClientRuntime_GetClientRuntime(@err,200);
//this function had no return value, (rt always nil) but no error return at err variable
if assigned(rt) then begin
......
end;
end;
我已经读过类似的问题,但它不能解决我的问题
有人能告诉我这里出了什么问题吗?我无法测试它,因为我没有
libSQLDBC\u C.dll
问题是。作为案例的解决方法,您可以在DelphiClientRuntime\u GetClientRuntime
声明中返回指针
ClientRuntime_GetClientRuntime: function (errorText:Pchar;
errorTextSize:Integer): Pointer; stdcall;
并将其转换到SQLDBC\u IRuntime
界面:
var
err : array [0..200] of char;
rt : SQLDBC_IRuntime;
begin
Pointer(rt):= ClientRuntime_GetClientRuntime(@err,200);
我无法测试它,因为我没有
libSQLDBC_C.dll
问题是。作为案例的解决方法,您可以在DelphiClientRuntime\u GetClientRuntime
声明中返回指针
ClientRuntime_GetClientRuntime: function (errorText:Pchar;
errorTextSize:Integer): Pointer; stdcall;
并将其转换到SQLDBC\u IRuntime
界面:
var
err : array [0..200] of char;
rt : SQLDBC_IRuntime;
begin
Pointer(rt):= ClientRuntime_GetClientRuntime(@err,200);
返回接口的C++函数不容易映射到Delphi函数。Delphi中托管类型返回值的调用约定与C++所使用的不匹配。p>
说明,我创建了一个简单的C++测试DLL,导出这个函数:
extern "C" __declspec(dllexport) IUnknown* __stdcall GetInterface()
{
CoInitialize(NULL);
IUnknown* result;
CoCreateInstance(CLSID_ActiveDesktop, NULL, CLSCTX_INPROC_SERVER,
IID_IUnknown, (void**) &result);
return result;
}
将其映射到Delphi的明显方式如下:
function GetInterface: IUnknown; stdcall; external DLL name '_GetInterface@0';
var
intf: IUnknown;
....
Pointer(intf) := GetInterface;
然而,当我们调用此函数时,它总是返回nil
解决方案完全符合Serg的建议:
function GetInterface: Pointer; stdcall; external DLL name '_GetInterface@0';
我们可以这样称呼它:
function GetInterface: IUnknown; stdcall; external DLL name '_GetInterface@0';
var
intf: IUnknown;
....
Pointer(intf) := GetInterface;
当我们这样做时,intf
不是nil
,我们可以非常愉快地调用它的方法
因此,我们在这里学到的是,Delphi无法轻松调用返回接口的外部函数,除非这些外部函数也在Delphi中实现。但至少我们有一个可行的解决办法
不幸的是,这种变通方法对您没有直接的用处。这是因为<代码> SqLDbcIrunTime/Cux>是C++类。它不是COM兼容的接口。请注意,
SQLDBC\u IRuntime
没有实现IInterface
。因此它不提供\u AddRef
,\u Release
和查询接口
。Delphi的接口支持取决于IInterface
的可用性。这意味着您不能使用Delphi中的SQLDBC\u IRuntime
您需要制作一个C++ DLL,它以Delphi调用的方式公开功能。例如,通过公开调用C++方法的普通旧函数,即代码> SqLDbcIrIunTime//>代码>
< P>一个返回接口的C++函数不容易映射到Delphi函数。Delphi中托管类型返回值的调用约定与C++所使用的不匹配。p>说明,我创建了一个简单的C++测试DLL,导出这个函数:
extern "C" __declspec(dllexport) IUnknown* __stdcall GetInterface()
{
CoInitialize(NULL);
IUnknown* result;
CoCreateInstance(CLSID_ActiveDesktop, NULL, CLSCTX_INPROC_SERVER,
IID_IUnknown, (void**) &result);
return result;
}
将其映射到Delphi的明显方式如下:
function GetInterface: IUnknown; stdcall; external DLL name '_GetInterface@0';
var
intf: IUnknown;
....
Pointer(intf) := GetInterface;
然而,当我们调用此函数时,它总是返回nil
解决方案完全符合Serg的建议:
function GetInterface: Pointer; stdcall; external DLL name '_GetInterface@0';
我们可以这样称呼它:
function GetInterface: IUnknown; stdcall; external DLL name '_GetInterface@0';
var
intf: IUnknown;
....
Pointer(intf) := GetInterface;
当我们这样做时,intf
不是nil
,我们可以非常愉快地调用它的方法
因此,我们在这里学到的是,Delphi无法轻松调用返回接口的外部函数,除非这些外部函数也在Delphi中实现。但至少我们有一个可行的解决办法
不幸的是,这种变通方法对您没有直接的用处。这是因为<代码> SqLDbcIrunTime/Cux>是C++类。它不是COM兼容的接口。请注意,
SQLDBC\u IRuntime
没有实现IInterface
。因此它不提供\u AddRef
,\u Release
和查询接口
。Delphi的接口支持取决于IInterface
的可用性。这意味着您不能使用Delphi中的SQLDBC\u IRuntime
您需要制作一个C++ DLL,它以Delphi调用的方式公开功能。例如,公开了调用C++代码方法的普通旧函数,即DLDPHI的哪个版本?你确定是stdcall吗?很有可能是cdecl。这让我想起了这个问题:@DavidHeffernan谢谢你的回答。stdcall和cdecl之间没有区别。我在Windows XP机器上,正在尝试Delphi 6、7和XE2。请确保使用AnsiChar for XE2。最好在这个库中始终使用它。尝试C++程序并检查它是否有效。如果是,有什么不同?这就是问题所在。它在C++、java和PHP上都有很好的应用。在Delphi6、7和XE2上,库成功地加载了返回字符串和数值的函数,但返回接口的所有函数除外。如果我使用接口,它将返回nil。如果我使用指针,它返回指针但抛出异常。哪个版本的Delphi?你确定是stdcall吗?很有可能是cdecl。这让我想起了这个问题:@DavidHeffernan谢谢你的回答。stdcall和cdecl之间没有区别。我在Windows XP机器上,正在尝试Delphi 6、7和XE2。请确保使用AnsiChar for XE2。最好在这个库中始终使用它。尝试C++程序并检查它是否有效。如果是,有什么不同?这就是问题所在。它在C++、java和PHP上都有很好的应用。在Delphi6、7和XE2上,库成功地加载了返回字符串和数值的函数,但返回接口的所有函数除外。如果我使用接口,它将返回nil。若我使用指针,它返回指针,但抛出异常;Delphi原型错误,因此返回值不会显示为函数的结果。@Serg您能详细说明一下吗?我想你的问题链接不适用于这里。有许多Win32 API函数返回COM接口,因此。我的直觉是问题在于
SQLDBC\u IRuntime
根本不是一个COM