从我的 Python 脚本中的 Delphi DLL 取回 PChar 参数
get PChar argument back from Delphi DLL in my Python script
假设我在 DLL 中有这个函数
function test_3(sInput, sOutput : PChar; sSize : int64): Integer; stdcall;
var
sTmp : string;
fText : TextFile;
begin
sTmp := '+++ ' + sInput + ' +++';
StrPLCopy(sOutput, PChar(sTmp), sSize);
Result := 69;
AssignFile(fText, 'test.txt');
Rewrite(fText);
Writeln(fText, 'in: ' + sInput);
Writeln(fText, 'out: ' + sOutput);
CloseFile(fText);
end;
在我的Delphi程序中,我这样称呼它
…
Input := EdtIn.Text;
OutputSize := Input.Length + 8;
Output := AllocMem(OutputSize);
RC := test_3(PChar(Input), Output, OutputSize);
EdtOut.Text := Output;
FreeMem(Output);
而且效果很好。现在我想从 Python 脚本中调用该函数。
import ctypes as ct
...
myString = "test Delphi 10.3 DLL"
outputsize = len(myString) + 8
…
test_3 = lib.test_3
test_3.restype = ct.c_int
test_3.argtypes = [ct.c_wchar_p, ct.c_wchar_p]
sOutput = ct.create_string_buffer(outputsize)
print("sOutput = " + sOutput.value)
然后出现错误
ctypes.ArgumentError: argument 2: : wrong type
所以我的问题是:Python 等价于 Delphi 中的 AllocMem 是什么。
我必须明确一点,当然所有代码都是示例,在 "real life" 中我无法访问 DLL 中的 Delphi 代码。
这是一个简单而完整的示例,演示了如何执行此操作:
Delphi图书馆
library SO_60391682;
uses
SysUtils;
function testStringOut(Input, Output: PChar; OutputLen: Int64): Integer; stdcall;
var
tmp: string;
begin
tmp := '+++ ' + Input + ' +++';
StrPLCopy(Output, PChar(tmp), OutputLen - 1);
// -1 because of StrPLCopy's handling of null terminator
Result := 0;
end;
exports
testStringOut;
begin
end.
Python 调用 Delphi 库的程序
import ctypes
lib = ctypes.WinDLL(r'SO_60391682.dll')
testStringOut = lib.testStringOut
testStringOut.restype = ctypes.c_int
testStringOut.argtypes = ctypes.c_wchar_p, ctypes.c_wchar_p, ctypes.c_int64
output = ctypes.create_unicode_buffer(256)
res = testStringOut('foo', output, len(output))
print('res={}, output={}'.format(res, output.value))
假设我在 DLL 中有这个函数
function test_3(sInput, sOutput : PChar; sSize : int64): Integer; stdcall;
var
sTmp : string;
fText : TextFile;
begin
sTmp := '+++ ' + sInput + ' +++';
StrPLCopy(sOutput, PChar(sTmp), sSize);
Result := 69;
AssignFile(fText, 'test.txt');
Rewrite(fText);
Writeln(fText, 'in: ' + sInput);
Writeln(fText, 'out: ' + sOutput);
CloseFile(fText);
end;
在我的Delphi程序中,我这样称呼它
…
Input := EdtIn.Text;
OutputSize := Input.Length + 8;
Output := AllocMem(OutputSize);
RC := test_3(PChar(Input), Output, OutputSize);
EdtOut.Text := Output;
FreeMem(Output);
而且效果很好。现在我想从 Python 脚本中调用该函数。
import ctypes as ct
...
myString = "test Delphi 10.3 DLL"
outputsize = len(myString) + 8
…
test_3 = lib.test_3
test_3.restype = ct.c_int
test_3.argtypes = [ct.c_wchar_p, ct.c_wchar_p]
sOutput = ct.create_string_buffer(outputsize)
print("sOutput = " + sOutput.value)
然后出现错误
ctypes.ArgumentError: argument 2: : wrong type
所以我的问题是:Python 等价于 Delphi 中的 AllocMem 是什么。 我必须明确一点,当然所有代码都是示例,在 "real life" 中我无法访问 DLL 中的 Delphi 代码。
这是一个简单而完整的示例,演示了如何执行此操作:
Delphi图书馆
library SO_60391682;
uses
SysUtils;
function testStringOut(Input, Output: PChar; OutputLen: Int64): Integer; stdcall;
var
tmp: string;
begin
tmp := '+++ ' + Input + ' +++';
StrPLCopy(Output, PChar(tmp), OutputLen - 1);
// -1 because of StrPLCopy's handling of null terminator
Result := 0;
end;
exports
testStringOut;
begin
end.
Python 调用 Delphi 库的程序
import ctypes
lib = ctypes.WinDLL(r'SO_60391682.dll')
testStringOut = lib.testStringOut
testStringOut.restype = ctypes.c_int
testStringOut.argtypes = ctypes.c_wchar_p, ctypes.c_wchar_p, ctypes.c_int64
output = ctypes.create_unicode_buffer(256)
res = testStringOut('foo', output, len(output))
print('res={}, output={}'.format(res, output.value))