我不止一次建议人们使用类型的返回值WideString进行互操作.
这个想法是a WideString和a一样BSTR.因为a BSTR是在共享COM堆上分配的,所以在一个模块中分配并在另一个模块中解除分配是没有问题的.这是因为所有各方都同意使用相同的堆,即COM堆.
但是,它似乎WideString不能用作互操作的函数返回值.
考虑以下Delphi DLL.
library WideStringTest;
uses
ActiveX;
function TestWideString: WideString; stdcall;
begin
Result := 'TestWideString';
end;
function TestBSTR: TBstr; stdcall;
begin
Result := SysAllocString('TestBSTR');
end;
procedure TestWideStringOutParam(out str: WideString); stdcall;
begin
str := 'TestWideStringOutParam';
end;
exports
TestWideString, TestBSTR, TestWideStringOutParam;
begin
end.
Run Code Online (Sandbox Code Playgroud)
和以下C++代码:
typedef BSTR (__stdcall *Func)();
typedef void (__stdcall *OutParam)(BSTR &pstr);
HMODULE lib = LoadLibrary(DLLNAME);
Func TestWideString = (Func) GetProcAddress(lib, "TestWideString"); …Run Code Online (Sandbox Code Playgroud) 我一直在尝试以下列方式调用在Delphi中创建的方法:
function _Func1(arrParams: array of TParams): Integer;stdcall;
type
TParams = record
Type: int;
Name: string;
Amount : Real;
end;
Run Code Online (Sandbox Code Playgroud)
我的代码是:
[DllImport("some.dll", EntryPoint = "_Func1", CallingConvention = CallingConvention.StdCall)]
public static extern int Func(
[MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.Struct)] TParams[] arrParams)
Run Code Online (Sandbox Code Playgroud)
结构是:
[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct TParams
{
public int Type;
[MarshalAs(UnmanagedType.AnsiBStr)]
public string Name;
public double Amount;
}
Run Code Online (Sandbox Code Playgroud)
当我调用此方法时,我收到错误:无法编组"TParams"类型的字段"名称":无效的托管/非托管类型组合(字符串字段必须与LPStr,LPWStr,BStr或ByValTStr配对).
然而,这些组合都不起作用,因为Delphi的字符串以其长度为前缀并且肯定是Ansi(我已经尝试了其他字符串参数).有谁有线索如何解决这个问题?