C#delphi弦乐弦乐

问题描述 投票:0回答:1
.

这是源代码:

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参数也损坏了:


可变名称
值 datatypeversion1375376intptr10x0000000000000008System.intptrptr20x00000000043e73c8System.intptrversion271189672intMARSHAL.PTRTOSTRINGBSTR(PSTR1)'marshal.ptrtostostringbstr(pstr1)'扔了一个例外'system.nullReferenceException'弦{system.nullReferenceException}marshal.ptrtostostringbstr(pstr2)“正常宽度”串 public static IntPtr Test(int version, IntPtr pstr1, IntPtr pstr2, int version2)PWideStringWideString
现在我将delphi中的返回类型更改为而不是
参数正确地传输到C#



可变名称

值 datatype

version8intptr10x000000000003259A88 0x000000000003257F987“正常宽度”marshal.ptrtostostringbstr(pstr2)”和这里的pwidestring” 串 问题是:为什么我需要将函数的返回类型声明为,而不仅是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
的呼叫约定。 delphi的默认调用undand justnution与c#不兼容。

此外,将一个变量打字到您的操作方式是错误的。

PWideString
期望指针,而不是指针。您需要更改
WideString
以接受
stdcall
值AS-IS(已经与
PTest
兼容)或
register
WideString
。不是一个

c# delphi interop bstr
1个回答
0
投票
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.