我想從Delphi XE5調用dll。從delphi調用c dll字符串
我花了一天左右的時間搜索諸如「從Delphi調用C DLL」之類的東西,並找到了一些頁面,但沒有什麼幫助。
我收到了如何調用該DLL在VB中的例子:
Declare Function IxCommand Lib "IxxDLL.dll" (ByVal command As String, ByVal mailbox As String) As Integer
...
Sub Command1_Click()
Dim command As String * 135
Dim mailbox As String * 135
command = "move:a,1000"
IxCommand(command, mailbox)
End Sub
還呼籲在VC++ 6.0的DLL:
#include "stdafx.h"
#include "windows.h"
#include "stdio.h"
#include "string.h"
typedef UINT (CALLBACK* LPFNIXDLLFUNC)(char *ixstr, char *mbstr);
int main(int argc, char* argv[])
{
HINSTANCE hDLL; // Handle to DLL
LPFNIXDLLFUNC lpfnIxDllFunc; // Function pointer
hDLL = LoadLibrary("IxxDLL.dll");
if (hDLL == NULL) // Fails to load Indexer LPT
{
printf("Can't open IxxDLL.dll\n");
exit(1);
}
else // Success opening DLL - get DLL function pointer
{
lpfnIxDllFunc = (LPFNIXDLLFUNC)GetProcAddress(hDLL, "IxCommand");
}
printf("Type Indexer LPT command and press <Enter> to send\n");
printf("Type \"exit\" and press <Enter> to quit\n\n");
while(1)
{
char ix_str[135]; // String to be sent to Indexer LPT
char mailbox_str[135]; // Results from call into Indexer LPT
gets(ix_str); // Get the string from the console
if(_stricmp(ix_str, "exit") == 0) // Leave this program if "exit"
break;
lpfnIxDllFunc(ix_str, mailbox_str); // Otherwise call into Indexer LPT
printf("%s\n\n", mailbox_str); // Print the results
}
FreeLibrary(hDLL);
return 0;
}
我注意到併發症是需要在調用DLL之前定義內存分配的大小,如上所示。
dll在第一個參數中接受一個命令,並在第二個參數中返回結果文本。
這是我生成的用於嘗試和調用DLL的Delphi代碼。我知道DLL加載,因爲它有一個啓動畫面顯示。我調用dll時不會生成錯誤。你會看到我使用數組來分配空間,然後將它們的位置分配給Pchar變量。我沒有任何原始DLL的頭文件,也沒有源代碼。你會看到我使用stdcall聲明瞭外部函數,但我也嘗試過沒有改變的cdecl。
問題:在arg2中返回的信息不是預期的文本字符串,而是一個翻譯爲非英文字符(看起來像中文)的字符串。
我猜我沒有發送正確的變量類型的DLL。
問題:任何人都可以幫助我制定外部函數的聲明並正確使用它,以便根據需要取回文本字符串?
見下文:
function IxCommand (command : PChar; mailbox : PChar) : Integer; stdcall; external 'IxxDLL.dll';
...
procedure TfrmXYZ.btn1Click(Sender: TObject);
var
LocalResult : Integer;
arg1,
arg2 : PChar;
ArrayStrCmd : array[0..134] of char;
ArrayStrMbx : array[0..134] of char;
begin
ArrayStrCmd := 'Accel?:a' + #0;
ArrayStrMbx := ' ' + #0;
arg1 := @ArrayStrCmd;
arg2 := @ArrayStrMbx;
LocalResult := IxCommand(arg1, arg2);
end;
AnsiString版本分配比具有固定長度數組的版本更小的緩衝區。你應該在這裏使用'SetLength'。並且不需要填充輸出緩衝區。 –
這真的取決於DLL函數的性質以及它的參數實際表示的內容。但無論如何,我已經更新了我的例子。 –
C代碼示例就是我們應該將其作爲模板的工具,而不是提問者的嘗試翻譯。它分配長度爲135的數組,並且不初始化郵箱的內容。 –