我不止一次建议人们使用类型的返回值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 DLL中的方法:
function SMap4Ovr(const OverFileName : ShortString ;
const Aclay : Integer ;
const Acarbon : Double ;
out errstr : ShortString): WordBool;
Run Code Online (Sandbox Code Playgroud)
我在C#中使用以下导入:
[DllImport("SMap.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
public static extern bool SMap4Ovr(
string OverFileName,
int Aclay,
double Acarbon,
out string errstr
);
Run Code Online (Sandbox Code Playgroud)
但我得到一个AccessViolationException.
我似乎能够调用DLL中的几个更简单的方法,这些方法有字符串参数但不是int或double.
我也试过CallingConvention = CallingConvention.Cdecl,但这给了我同样的错误.