。
这是源代码:
using System.Runtime.InteropServices;
using System.Windows;
namespace DNNETests
{
public class Class1
{
[UnmanagedCallersOnly]
public static void Attach()
{
MessageBox.Show("Hallo c# debugger");
}
[StructLayout(LayoutKind.Sequential)]
public struct IsInputFileVersionCompatibleResult
{
public int resultCode;
public IntPtr msg;
public IntPtr mostRecentRelatedPPPVersion;
}
[UnmanagedCallersOnly]
public static IntPtr Test(int version, IntPtr pstr1, IntPtr pstr2, int version2)
{
string str1 = Marshal.PtrToStringBSTR(pstr1) ?? string.Empty;
string str2 = Marshal.PtrToStringBSTR(pstr2) ?? string.Empty;
MessageBox.Show("parameter: " + version+Environment.NewLine+
str1+Environment.NewLine+
str2+Environment.NewLine+
version2);
return Marshal.StringToBSTR("return value");
}
}
}
我有一个消耗dll的delphi应用程序:
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs;
type
PAttachToDLL = procedure();
PTest = function(version : Integer; str1: WideString; str2 : PWideString; version2 : integer):WideString;
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
dllAttachToDLL: PAttachToDLL;
dllTest : PTest;
procedure makeTestCall;
public
{ Public-Deklarationen }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var
dllhandle: THandle;
begin
dllhandle := SafeLoadLibrary('C:\path\to\DNNETests\bin\Debug\net8.0-windows7.0\DNNETestsNE.dll');
@dllAttachToDLL := GetProcAddress(dllhandle, 'Attach');
@dllTest := GetProcAddress(dllhandle, 'Test');
dllAttachToDLL();
makeTEstCall();
Application.Terminate();
end;
procedure TForm1.makeTestCall();
var
tmp:WideString;
ptmp : PWideString;
str1 : WideString;
str2 : WideString;
begin
str1:=WideString('normal widestring');
str2:=WideString('and here pwidestring');
// ptmp:=dllTest(8, str1, PWideString(str2), 7);
tmp:=dllTest(8, (str1), PWideString(str2), 7);
tmp:=WideString(ptmp);
ShowMessage(tmp);
end;
end.
当与C#进入的调试器停止时,我可以看到两个整数参数都被破坏了,并且第一个INTPTR参数也损坏了:
可变名称
public static IntPtr Test(int version, IntPtr pstr1, IntPtr pstr2, int version2)
PWideString
WideString
现在我将delphi中的返回类型更改为 | 而不是 |
可变名称值 datatype
PWideString
,为什么我不需要将字符串参数从delphi发送到c#as c#也为? (关于两个参数,一个是另一个参数)
在Delphi方面,您忘了指定PWideString
为System.intptr | ptr2 | |
System.intptr | version2 | |
int | MARSHAL.PTRTOSTRINGBSTR(PSTR1) | |
串 | ||
PTest = function(version : Integer; str1: WideString; str2 : PWideString; version2 : integer):PWideString; | ||
WideString | ) |
str
此外,将一个变量打字到您的操作方式是错误的。
PWideString
期望指针,而不是指针。您需要更改WideString
以接受stdcall
值AS-IS(已经与PTest
兼容)或register
WideString
。不是一个