LPBYTE в C#
Код:
IeOutput (UINT16 pad, UINT16 sad, LPBYTE buffer, LPUINT16 count);
вот мой код для вызова на с#.
Как мне передать LPBYTE и LPUINT16?
Код:
[DllImport("ie488f3w.dll", CharSet = CharSet.Auto, CallingConvention=CallingConvention.ThisCall)]
public static extern short IeOutput(UInt16 pad, UINT16 sad, ХХХ, YYY);
public GPIB()
{
IeOutput(IEE488types.DEVADR, IEE488types.IE_NOSAD, [COLOR="Red"]XXX[/COLOR], [COLOR="Red"]YYY[/COLOR]);
}
public static extern short IeOutput(UInt16 pad, UINT16 sad, ХХХ, YYY);
public GPIB()
{
IeOutput(IEE488types.DEVADR, IEE488types.IE_NOSAD, [COLOR="Red"]XXX[/COLOR], [COLOR="Red"]YYY[/COLOR]);
}
Код:
// IeOutput (UINT16 pad, UINT16 sad, LPBYTE buffer, LPUINT16 count);
[DllImport("ie488f3w.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.ThisCall)]
public static extern short IeOutput(ushort pad, ushort sad, byte[] buffer, ref ushort count);
[DllImport("ie488f3w.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.ThisCall)]
public static extern short IeOutput(ushort pad, ushort sad, byte[] buffer, ref ushort count);
А вы уверены в соглашении вызова? Точно не stdcall?
А передать параметры у меня так и не вышло.
Вот что есть на с++. Если можно напишите, как это должно выглядеть на С#.
Код:
char *buf = new char;
strcpy(buf,"*IDN?");
cnt=strlen(buf);
IeOutput(DEVADR,IE_NOSAD,(LPBYTE)buf,(LPUINT16)&cnt);
strcpy(buf,"*IDN?");
cnt=strlen(buf);
IeOutput(DEVADR,IE_NOSAD,(LPBYTE)buf,(LPUINT16)&cnt);
Цитата: 2504
А передать параметры у меня так и не вышло.
Вот что есть на с++. Если можно напишите, как это должно выглядеть на С#.
Вот что есть на с++. Если можно напишите, как это должно выглядеть на С#.
Код:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace ConsoleApplication7 {
class Program {
// IeOutput (UINT16 pad, UINT16 sad, LPBYTE buffer, LPUINT16 count);
[DllImport("ie488f3w.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.ThisCall)]
public static extern short IeOutput(ushort pad, ushort sad, byte[] buffer, ref ushort count);
static void Main(string[] args) {
string str = "*IDN?";
byte[] buffer = Encoding.ASCII.GetBytes(str);
ushort count = (ushort)buffer.Length;
IeOutput(IEE488types.DEVADR, IEE488types.IE_NOSAD, buffer, ref count);
}
}
}
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace ConsoleApplication7 {
class Program {
// IeOutput (UINT16 pad, UINT16 sad, LPBYTE buffer, LPUINT16 count);
[DllImport("ie488f3w.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.ThisCall)]
public static extern short IeOutput(ushort pad, ushort sad, byte[] buffer, ref ushort count);
static void Main(string[] args) {
string str = "*IDN?";
byte[] buffer = Encoding.ASCII.GetBytes(str);
ushort count = (ushort)buffer.Length;
IeOutput(IEE488types.DEVADR, IEE488types.IE_NOSAD, buffer, ref count);
}
}
}
Далее вопрос: что возвращает функция IeOutput? Я так и не увидел ее полного прототипа, покажите как она объявлена в библиотеке.
Код:
typedef short int E488
#define IE_EXPORT extern E488 FAR PASCAL
IE_EXPORT IeOutput (UINT16 pad, UINT16 sad, LPBYTE buffer, LPUINT16 count);
IE_EXPORT IeEnter (UINT16 pad, UINT16 sad, LPBYTE buffer, LPUINT16
count);
#define IE_EXPORT extern E488 FAR PASCAL
IE_EXPORT IeOutput (UINT16 pad, UINT16 sad, LPBYTE buffer, LPUINT16 count);
IE_EXPORT IeEnter (UINT16 pad, UINT16 sad, LPBYTE buffer, LPUINT16
count);
Это мы отправляем запрос на прибор
Код:
#define DEVADR 713//GPIB addr device
#define IE_NOSAD (UINT16) (-1) /* secondary address not used
char *buf = new char;
strcpy(buf,"*IDN?");
cnt=strlen(buf);
IeOutput(DEVADR,IE_NOSAD,(LPBYTE)buf,(LPUINT16)&cnt);
#define IE_NOSAD (UINT16) (-1) /* secondary address not used
char *buf = new char;
strcpy(buf,"*IDN?");
cnt=strlen(buf);
IeOutput(DEVADR,IE_NOSAD,(LPBYTE)buf,(LPUINT16)&cnt);
Тут читаем ответ
Код:
#define IE_CNTBYTE 1000
char *bufAnswer = new char[IE_CNTBYTE];
IeEnter(DEVADR,IE_NOSAD,(LPBYTE)buf2,(LPUINT16)&IE_CNTBYTE);
char *bufAnswer = new char[IE_CNTBYTE];
IeEnter(DEVADR,IE_NOSAD,(LPBYTE)buf2,(LPUINT16)&IE_CNTBYTE);
Код:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace ConsoleApplication16 {
class Program {
public const ushort DEVADR = 713;
public const ushort IE_NOSAD = 0xFFFF; // -1
[DllImport("ie488f3w.dll", CallingConvention = CallingConvention.StdCall)]
public static extern short IeOutput(ushort pad, ushort sad, byte[] buffer, ref ushort count);
[DllImport("ie488f3w.dll", CallingConvention = CallingConvention.StdCall)]
public static extern short IeEnter(ushort pad, ushort sad, byte[] buffer, ref ushort count);
static void Main(string[] args) {
string str = "*IDN?";
byte[] buffer = Encoding.ASCII.GetBytes(str);
ushort count = (ushort)buffer.Length;
short result = IeOutput(DEVADR, IE_NOSAD, buffer, ref count);
}
}
}
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace ConsoleApplication16 {
class Program {
public const ushort DEVADR = 713;
public const ushort IE_NOSAD = 0xFFFF; // -1
[DllImport("ie488f3w.dll", CallingConvention = CallingConvention.StdCall)]
public static extern short IeOutput(ushort pad, ushort sad, byte[] buffer, ref ushort count);
[DllImport("ie488f3w.dll", CallingConvention = CallingConvention.StdCall)]
public static extern short IeEnter(ushort pad, ushort sad, byte[] buffer, ref ushort count);
static void Main(string[] args) {
string str = "*IDN?";
byte[] buffer = Encoding.ASCII.GetBytes(str);
ushort count = (ushort)buffer.Length;
short result = IeOutput(DEVADR, IE_NOSAD, buffer, ref count);
}
}
}
Коль не заработает - сделаю библиотеку "заглушку". :)
[QUOTE=hardcase]Если, я не ошибаюсь, то PASCAL современные компиляторы разворачивают в __stdcall[/QUOTE]Совершенно верно. __thiscall - соглашение о вызове нестатичных методов С++-классов. В данном случае, соглашение о вызове можно не указывать явно.
хидер
Код:
extern "C" TEST short _IeOutput(short pad, short sad, string buffer, short count);
.срр
Код:
short _IeOutput(short pad, short sad, string sCommand, short count)
{
const char* buf = new char;
buf = sCommand.c_str();
short isize = strlen(buf);
return IeOutput(pad, sad, (LPBYTE)buf, (LPUINT16)&isize);
}
{
const char* buf = new char;
buf = sCommand.c_str();
short isize = strlen(buf);
return IeOutput(pad, sad, (LPBYTE)buf, (LPUINT16)&isize);
}
вызов в C#
Код:
string str = "*IDN?";
short count = (short)str.Length;
_IeOutput(ieee488.DEVADR, ieee488.IE_NOSAD, str, count);
short count = (short)str.Length;
_IeOutput(ieee488.DEVADR, ieee488.IE_NOSAD, str, count);
И новая проблема
Код:
Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
как я понял, проблема в размере C#(string) и C(string).
Как передать из C# в длл строку?
Ох.. Ну попробуйте C++/CLI-враппер сделать:
Код:
using namespace System;
using namespace System::Text;
public ref class Ie
{
public:
static unsigned short Output (unsigned short pad, unsigned short sad, String ^ string)
{
array<unsigned char, 1> ^ bytes = Encoding::ASCII->GetBytes(string);
unsigned short s = (unsigned short) bytes->Length;
pin_ptr<unsigned char> ptr = &bytes[0];
// оригинал
return ::IeOutput(pad, sad, ptr, &s);
}
};
using namespace System::Text;
public ref class Ie
{
public:
static unsigned short Output (unsigned short pad, unsigned short sad, String ^ string)
{
array<unsigned char, 1> ^ bytes = Encoding::ASCII->GetBytes(string);
unsigned short s = (unsigned short) bytes->Length;
pin_ptr<unsigned char> ptr = &bytes[0];
// оригинал
return ::IeOutput(pad, sad, ptr, &s);
}
};
Код:
Ie.Output(ieee488.DEVADR, ieee488.IE_NOSAD, "Hallo!");
Код:
[DllImport("ie488f3w.dll", CharSet = CharSet.Ansi]
public static extern short IeOutput(ushort pad, ushort sad, string buffer, ref ushort count);
...
string str = "Hallo!"
ushort count = (ushort) str.Length;
IeOutput(IEE488types.DEVADR, IEE488types.IE_NOSAD, str, ref count);
public static extern short IeOutput(ushort pad, ushort sad, string buffer, ref ushort count);
...
string str = "Hallo!"
ushort count = (ushort) str.Length;
IeOutput(IEE488types.DEVADR, IEE488types.IE_NOSAD, str, ref count);
Код:
char *buf = new char;
здесь
Код:
byte[] buffer = Encoding.ASCII.GetBytes(str);
ushort count = (ushort)buffer.Length;
short result = IeOutput(DEVADR, IE_NOSAD, buffer, ref count);
ushort count = (ushort)buffer.Length;
short result = IeOutput(DEVADR, IE_NOSAD, buffer, ref count);
прибор не отвечает.
Вот я и решил сделать обертку с другой длл, чтобы строку в дллку передавать, а там уже вызывать другую длл и передавать ей указатель.
В с++(тестовая програмка) все работает. В С# проблема с передачей строки опять вылезла. С понедельника попробую враппер.
П.С. Спасибо за помощь.
Цитата: 2504
В с++(тестовая програмка) все работает. В С# проблема с передачей строки опять вылезла. С понедельника попробую враппер.
Может быть нужен нуль-символ в конце строки?
Стоит попробовать:
Код:
[DllImport("ie488f3w.dll", CharSet = CharSet.Ansi]
public static extern short IeOutput(ushort pad, ushort sad, string buffer, ref ushort count);
...
string str = "Hallo!"
ushort count = (ushort) str.Length;
IeOutput(IEE488types.DEVADR, IEE488types.IE_NOSAD, str, ref count);
public static extern short IeOutput(ushort pad, ushort sad, string buffer, ref ushort count);
...
string str = "Hallo!"
ushort count = (ushort) str.Length;
IeOutput(IEE488types.DEVADR, IEE488types.IE_NOSAD, str, ref count);
[QUOTE=hardcase]Может быть нужен нуль-символ в конце строки?[/QUOTE]Кросафчег :)
А на враппере-то у меня код прошёл тогда...