Новый программист нуждается в помощи!
Код 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);
}
}
Ваша 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
}