Как мне вызвать этот метод Delphi в C # с помощью Dllimport?

1

Новый программист нуждается в помощи!

Код Delphi, который скомпилирован в DLL

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;

Код С#

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

Мне нужно сохранить значение указателя, Size и Msg в буфере и напечатать значение в окне консоли.

Я очень признателен за полностью построенный код. Заранее спасибо.

Вот код, который я до сих пор пробовал. // Код С#

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);
     }
}
  • 0
    Ваша функция Delphi экспортируется?
  • 0
    @Jerry Функция delphi хранится в dll с именем «Test.dll». Я должен был импортировать ее в c #, мне нужно создать графический интерфейс, который будет взаимодействовать между USB-устройством через dll.
Показать ещё 7 комментариев
Теги:
pinvoke
dllimport

1 ответ

2
Лучший ответ

Ваша DLL-функция спроектирована неправильно. Вы передаете строку из вызывающего кода в DLL. Это очень просто сделать, и вы можете удалить почти весь свой код. Код Delphi должен выглядеть следующим образом:

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

Тогда код С# должен быть:

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

Вызвать функцию следующим образом:

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

Я заменил ваше целочисленное возвращаемое значение логическим показателем успеха или неудачи. Если вы предпочитаете возвращать целое число, которое будет выглядеть так:

Delphi

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

С#

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

Обновить

Очевидно, вы не можете изменить эту DLL. Это позор, потому что это действительно очень плохо спроектировано и реализовано. Однако для вызова этой функции из С# вам нужно объявить p/invoke следующим образом:

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

И затем назовите это так:

byte[] Msg = Encoding.Default.GetBytes(serial);
int retval = SetCurrentSerial(Msg.Length, Msg);
if (retval != 0)
{
    // handle error
}
  • 0
    Спасибо @David за вашу помощь, я сейчас пойду домой, постараюсь реализовать этот код, а также предыдущий код и свяжусь с вами позже.
  • 0
    код Delphi хранится в dll, его нельзя изменить, и он отлично работает с дизайном GUI с Boland, я хочу создавать GUI с Visual C #, его развод с Delphi, но мне нужно, чтобы dll и все его функции были импортируется в C #.
Показать ещё 19 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню