简体   繁体   English

如何使用Dllimport在C#中调用此Delphi方法?

[英]How do I call this Delphi method in C# using Dllimport?

New Programmer in need of Help! 新程序员需要帮助!

The Delphi code that is compiled into the DLL 编译到DLL中的Delphi代码

function SetCurrentSerial(Size : Integer; Msg : Pointer) : Integer stdcall;
var
  TempByte : PByte;
  TempStr : string;
  i: Integer;
begin
  Result := 0;
  TempByte := Msg;
  TempStr := '';
  for i := 0 to Size - 1 do
  begin
    TempStr := TempStr + ' ';
  end;

  for i := 0 to Size - 1 do
  begin
    TempStr[i+1] := Chr(TempByte^);
    Inc(TempByte);
  end;

  if not DLLClass.SelectDeviceSerial(TempStr) then
  begin
    Result := -1;
  end;
end;

The C# Code C#代码

//Import a Function Pointer
[DllImport("Test.dll", CallingConvention= CallingConvention.StdCall, CharSet =  CharSet.Ansi)]
public unsafe static extern int SetCurrentSerial(int Size, byte[] Msg);

I need to store the pointer value, Size and Msg in a buffer and print the value in a console window. 我需要将指针值,大小和消息存储在缓冲区中,然后在控制台窗口中打印该值。

I will greatly appreciate a fully constructed code. 我将不胜感激完整构建的代码。 Thank you in advance. 先感谢您。

Here is the code I've so far tried. 这是我到目前为止尝试过的代码。 //C# Code // C#代码

class Program
{
    [DllImport("Test.dll")]
    public unsafe static extern int SetCurrentSerial(int Size, void* Msg); 

    unsafe static void Main()
     {
        int Res;

        byte[] buffer = new byte[1024];

        Res = SetCurrentSerial(255, &buffer);

        Console.WriteLine("%s\n", buffer);
     }
}

Your DLL function is designed incorrectly. 您的DLL函数设计不正确。 You are passing a string from the calling code to the DLL. 您正在将字符串从调用代码传递到DLL。 That is really simple to do and you can remove almost all of your code. 这真的很简单,您可以删除几乎所有代码。 The Delphi code should be like this: Delphi代码应如下所示:

function SetCurrentSerial(Serial: PAnsiChar): LongBool; stdcall;
begin
  Result := DLLClass.SelectDeviceSerial(Serial);
end;

Then the C# code should be: 然后,C#代码应为:

[DllImport("Test.dll", CallingConvention = CallingConvention.StdCall, 
    CharSet = CharSet.Ansi)]
public static extern bool SetCurrentSerial(string Serial);

Call the function like this: 像这样调用函数:

bool succeeded = SetCurrentSerial(Serial);
if (!succeeded)
{
    // handle error
}

I've replaced your integer return value with a boolean indicating success or failure. 我已经用指示成功或失败的布尔值替换了您的整数返回值。 Should you prefer to revert to an integer that would look like this: 您是否希望还原为如下所示的整数:

Delphi 德尔福

function SetCurrentSerial(Serial: PAnsiChar): Integer; stdcall;
begin
  if DLLClass.SelectDeviceSerial(Serial) then begin
    Result := 0;
  end else begin
    Result := -1;
  end;
end;

C# C#

[DllImport("Test.dll", CallingConvention = CallingConvention.StdCall, 
    CharSet = CharSet.Ansi)]
public static extern int SetCurrentSerial(string Serial);

Update 更新

Apparently you cannot change this DLL. 显然,您不能更改此DLL。 That is a shame because it is really very badly designed and implemented. 真可惜,因为它的设计和实现确实非常糟糕。 However, to call that function from C# you need to declare the p/invoke like this: 但是,要从C#调用该函数,您需要像这样声明p / invoke:

[DllImport("Test.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int SetCurrentSerial(int Size, byte[] Msg);

And then call it like this: 然后这样称呼它:

byte[] Msg = Encoding.Default.GetBytes(serial);
int retval = SetCurrentSerial(Msg.Length, Msg);
if (retval != 0)
{
    // handle error
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM