Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

LPBYTE в C#

14K
13 мая 2009 года
2504
33 / / 27.03.2007
Есть dll(написаная на с++) с которой мне нужно вызвать функцию.

 
Код:
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]);
           
        }
5
13 мая 2009 года
hardcase
4.5K / / 09.08.2005
Так попробуйте:
 
Код:
// 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);

А вы уверены в соглашении вызова? Точно не stdcall?
14K
13 мая 2009 года
2504
33 / / 27.03.2007
По поводу соглашения вызова не уверен:)

А передать параметры у меня так и не вышло.
Вот что есть на с++. Если можно напишите, как это должно выглядеть на С#.

 
Код:
char *buf = new char;
   
    strcpy(buf,"*IDN?");
    cnt=strlen(buf);
    IeOutput(DEVADR,IE_NOSAD,(LPBYTE)buf,(LPUINT16)&cnt);
5
13 мая 2009 года
hardcase
4.5K / / 09.08.2005
Цитата: 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);
        }
    }
}

Далее вопрос: что возвращает функция IeOutput? Я так и не увидел ее полного прототипа, покажите как она объявлена в библиотеке.
14K
14 мая 2009 года
2504
33 / / 27.03.2007
это с хидера
 
Код:
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 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_CNTBYTE  1000
char *bufAnswer = new char[IE_CNTBYTE];

    IeEnter(DEVADR,IE_NOSAD,(LPBYTE)buf2,(LPUINT16)&IE_CNTBYTE);
5
14 мая 2009 года
hardcase
4.5K / / 09.08.2005
Хмм похоже что вот так должно быть:
Код:
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);
        }
    }
}
Если, я не ошибаюсь, то PASCAL современные компиляторы разворачивают в __stdcall.

Коль не заработает - сделаю библиотеку "заглушку". :)
341
14 мая 2009 года
Der Meister
874 / / 21.12.2007
[QUOTE=hardcase]Если, я не ошибаюсь, то PASCAL современные компиляторы разворачивают в __stdcall[/QUOTE]Совершенно верно. __thiscall - соглашение о вызове нестатичных методов С++-классов. В данном случае, соглашение о вызове можно не указывать явно.
14K
15 мая 2009 года
2504
33 / / 27.03.2007
Сделал обертку из другой длл.

хидер

 
Код:
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);

}


вызов в C#
 
Код:
string str = "*IDN?";
           
            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# в длл строку?
341
15 мая 2009 года
Der Meister
874 / / 21.12.2007
System.String не маршаллится в std::string. Кроме того, в .NET для строк используется единокод, а в stl - многобайт.
Ох.. Ну попробуйте 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);
    }
};
Из C# вызывать будете так:
 
Код:
Ie.Output(ieee488.DEVADR, ieee488.IE_NOSAD, "Hallo!");
, xотя hardcase показал вам вполне себе отличное решение - должно работать. Ну можно было так ещё:
 
Код:
[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);
P.S. И, кстати, никогда не делайте так:
 
Код:
char *buf = new char;
14K
15 мая 2009 года
2504
33 / / 27.03.2007
Я благодарен hardcase"у за помощь. Без него я бы этот девайс не запустил. Он дал действительно толковые советы. Но
здесь
 
Код:
byte[] buffer = Encoding.ASCII.GetBytes(str);
            ushort count = (ushort)buffer.Length;
            short result = IeOutput(DEVADR, IE_NOSAD, buffer, ref count);


прибор не отвечает.

Вот я и решил сделать обертку с другой длл, чтобы строку в дллку передавать, а там уже вызывать другую длл и передавать ей указатель.
В с++(тестовая програмка) все работает. В С# проблема с передачей строки опять вылезла. С понедельника попробую враппер.

П.С. Спасибо за помощь.
5
16 мая 2009 года
hardcase
4.5K / / 09.08.2005
Цитата: 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);
341
16 мая 2009 года
Der Meister
874 / / 21.12.2007
[QUOTE=hardcase]Может быть нужен нуль-символ в конце строки?[/QUOTE]Кросафчег :)
341
16 мая 2009 года
Der Meister
874 / / 21.12.2007
А на враппере-то у меня код прошёл тогда...
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог