我不止一次建议人们使用类型的返回值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) David对另一个问题的回答显示Delphi DLL函数返回一个WideString.我从没想过如果没有使用它是可能的ShareMem.
我的测试DLL:
function SomeFunction1: Widestring; stdcall;
begin
Result := 'Hello';
end;
function SomeFunction2(var OutVar: Widestring): BOOL; stdcall;
begin
OutVar := 'Hello';
Result := True;
end;
Run Code Online (Sandbox Code Playgroud)
我的来电计划:
function SomeFunction1: WideString; stdcall; external 'Test.dll';
function SomeFunction2(var OutVar: Widestring): BOOL; stdcall; external 'Test.dll';
procedure TForm1.Button1Click(Sender: TObject);
var
W: WideString;
begin
ShowMessage(SomeFunction1);
SomeFunction2(W);
ShowMessage(W);
end;
Run Code Online (Sandbox Code Playgroud)
它有效,我不明白怎么做.我所知道的约定是Windows API使用的约定,例如Windows GetClassNameW:
function GetClassNameW(hWnd: HWND; lpClassName: PWideChar; nMaxCount: Integer): Integer; stdcall;
Run Code Online (Sandbox Code Playgroud)
意味着调用者提供缓冲区和最大长度.Windows DLL以长度限制写入该缓冲区.调用者分配和释放内存.
另一种选择是DLL分配内存,例如通过使用LocalAlloc,并且调用者通过调用释放内存LocalFree.
内存分配和解除分配如何与我的DLL示例一起使用?"魔法"是否会发生,因为结果是WideString(BSTR …
当我调用Dll方法时,它有时会引发异常,有时则不会.
我这样称呼它:
public class DllTest
{
[DllImport(@"MyDll.dll")]
public extern static string MyMethod(string someStringParam);
}
class Program
{
static void Main(string[] args)
{
DllTest.MyMethod("SomeString");
}
}
Run Code Online (Sandbox Code Playgroud)
我有时得到的例外是:
AccessViolationException
Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
AccessViolationException
Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
AccessViolationException
Attempted to read or write protected memory. This is often an indication that other memory …