Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.72/25: Рейтинг темы: голосов - 25, средняя оценка - 4.72
1 / 1 / 0
Регистрация: 04.09.2014
Сообщений: 21

Вызов функций, возвращающих указатель на структуру, из нативной dll

09.11.2016, 08:53. Показов 5215. Ответов 33
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Тут на форуме уже не раз задавали вопросы, как вызвать функцию из нативной dll. И в случае, если функция возвращает "нормальный" тип, у меня с этим вопросов нет: DllImport и всё такое. Но вот если функция возвращает указатель на интерфейс, вот тут у меня возникли проблемы.
Имеется dll-ка (написана, кажется, на CBuilder), экспортирующая всего 2 функции. Так же имеются примеры работы с этой dll-кой в Delphi и в С++.

На Delphi это выглядит так:

Rtusbapi.pas

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
unit Rtusbapi;
 
interface
 
uses
    windows;
 
type
pSHORT = ^SHORT;
pBYTE = ^BYTE;
 
type
 
// структура, задающая режимы ввода данных для модуля USB-3000
INPUT_PARS_USB3000 = packed record   // (size=438)
    size : WORD;
    InputEnabled : BOOL;                                    // флажок разрешение/запрещение ввода данных (только при чтении)
    CorrectionEnabled : BOOL;                           // управление корректировкой входных данных (с АЦП)
    InputClockSource : WORD;                            // источник тактовых импульсов для ввода данных
    InputType : WORD;                                       // тип вводимых с модуля даных (АЦП или ТТЛ)
    SynchroType : WORD;                                 // тип синхронизации вводимых с модуля даных
    SynchroAdType : WORD;                               // тип аналоговой синхронизации
    SynchroAdMode : WORD;                               // режим аналоговой сихронизации
    SynchroAdChannel : WORD;                            // канал АЦП при аналоговой синхронизации
    SynchroAdPorog : SHORT;                             // порог срабатывания АЦП при аналоговой синхронизации
    ChannelsQuantity : WORD;                            // число активных логических каналов
    ControlTable : array [0..127] of WORD;          // управляющая таблица с активными логическими каналами
    InputFifoBaseAddress : WORD;                        // базовый адрес FIFO буфера ввода
    InputFifoLength : WORD;                             // длина FIFO буфера ввода
    InputRate : double;                                 // тактовая частота ввода данных в кГц
    InterKadrDelay : double;                            // межкадровая задержка в мс
    ChannelRate : double;                               // частота ввода фиксированного логического канала
    AdcOffsetCoef : array [0..7] of double;         // корректировочные коэф. смещение нуля для АЦП
    AdcScaleCoef : array [0..7] of double;          // корректировочные коэф. масштаба для АЦП
end;
pINPUT_PARS_USB3000 = ^INPUT_PARS_USB3000;
 
// структура, задающая режимы вывода данных для модуля USB-3000
OUTPUT_PARS_USB3000 = packed record    // (size = 18)
    size : WORD;
    OutputEnabled : BOOL;                               // разрешение/запрещение вывода данных
    OutputRate : double;                                    // частота вывода данных в кГц
    OutputFifoBaseAddress : WORD;                   // базовый адрес FIFO буфера вывода
    OutputFifoLength : WORD;                            // длина FIFO буфера вывода
end;
pOUTPUT_PARS_USB3000 = ^OUTPUT_PARS_USB3000;
 
// структура пользовательского ППЗУ
FLASH_USB3000 = packed record           // (size = 256)
    CRC16 : WORD;                                           // контрольная сумма
    size : WORD;                                            // размер структуры
    SerialNumber : array [0..8] of BYTE;            // серийный номер модуля
    Name : array [0..10] of BYTE;                       // название модуля
    Revision : CHAR;                                        // ревизия модуля
    DspType : array [0..16] of BYTE;                    // тип установленного DSP
    IsDacPresented : BYTE;                              // флажок наличия ЦАП
    DspClockout : DWORD;                                // тактовая частота DSP в Гц
    AdcOffsetCoef : array [0..7] of single;         // корректировочные коэф. смещения нуля для АЦП
    AdcScaleCoef : array [0..7] of single;          // корректировочные коэф. масштаба для АЦП
    DacOffsetCoef : array [0..1] of single;         // корректировочные коэф. смещения нуля для ЦАП
    DacScaleCoef : array [0..1] of single;          // корректировочные коэф. масштаба для ЦАП
    ReservedByte : array [0..128] of BYTE;          // зарезервировано
end;
pFLASH_USB3000 = ^FLASH_USB3000;
 
// структура, содержащая информацию о версии драйвера DSP
DSP_INFO_USB3000 = packed record    // (size = 18)
    Target : array [0..9] of BYTE;                  //  модуль, для которого предназначен данный драйвер DSP
    DrvLabel : array [0..5] of BYTE;                    // метка разработчика драйвера DSP
    DspMajor : BYTE;                                        // старшие число версии драйвера DSP
    DspMinor : BYTE;                                        // младшее число версии драйвера DSP
end;
pDSP_INFO_USB3000 = ^DSP_INFO_USB3000;
 
// интерфейс модуля USB3000                                       `
IRTUSB3000 = class
  public
    // USB интерфейс модуля
    Function OpenDevice(VirtualSlot : WORD) : boolean; virtual; stdcall; abstract;
    Function CloseDevice : boolean; virtual; stdcall; abstract;
    Function GetModuleHandle : THandle; virtual; stdcall; abstract;
    Function GetUsbSpeed(UsbSpeed : pByte) : boolean; virtual; stdcall; abstract;
    Function GetModuleName(ModuleName : pCHAR) : boolean; virtual; stdcall; abstract;
    Function GetModuleSerialNumber(SerialNumber : pCHAR) : boolean; virtual; stdcall; abstract;
    Function GetAvrVersion(AvrVersion : pCHAR) : boolean; virtual; stdcall; abstract;
    Function ReleaseInstance : boolean; virtual; stdcall; abstract;
 
    // функции для работы с DSP модуля
    Function RESET_DSP : boolean; virtual; stdcall; abstract;
    Function LOAD_DSP(FileName : pCHAR = nil) : boolean; virtual; stdcall; abstract;
    Function MODULE_TEST : boolean; virtual; stdcall; abstract;
    Function GET_DSP_INFO(DspInfo : pDSP_INFO_USB3000): boolean; virtual; stdcall; abstract;
    Function SEND_COMMAND(Command : WORD) : boolean; virtual; stdcall; abstract;
 
    // функции для работы с памятью DSP модуля
    Function PUT_VAR_WORD(Address : WORD; Data : SHORT) : boolean; virtual; stdcall; abstract;
    Function GET_VAR_WORD(Address : WORD; Data : pSHORT) : boolean; virtual; stdcall; abstract;
    Function PUT_DM_WORD(Address : WORD; Data : SHORT) : boolean; virtual; stdcall; abstract;
    Function GET_DM_WORD(Address : WORD; Data : pSHORT) : boolean; virtual; stdcall; abstract;
    Function PUT_PM_WORD(Address : WORD; Data : DWORD) : boolean; virtual; stdcall; abstract;
    Function GET_PM_WORD(Address : WORD; Data : pDWORD) : boolean; virtual; stdcall; abstract;
    Function PUT_DM_ARRAY(BaseAddress, NPoints : WORD; Data : pSHORT) : boolean; virtual; stdcall; abstract;
    Function GET_DM_ARRAY(BaseAddress, NPoints : WORD; Data : pSHORT) : boolean; virtual; stdcall; abstract;
    Function PUT_PM_ARRAY(BaseAddress, NPoints : WORD; Data : pDWORD) : boolean; virtual; stdcall; abstract;
    Function GET_PM_ARRAY(BaseAddress, NPoints : WORD; Data : pDWORD) : boolean; virtual; stdcall; abstract;
 
    // функции для работы в режиме ввода данных
    Function GET_INPUT_PARS(ap : pINPUT_PARS_USB3000) : boolean; virtual; stdcall; abstract;
    Function SET_INPUT_PARS(ap : pINPUT_PARS_USB3000) : boolean; virtual; stdcall; abstract;
    Function START_READ : boolean; virtual; stdcall; abstract;
    Function STOP_READ : boolean; virtual; stdcall; abstract;
    Function READ_KADR(Data : pSHORT) : boolean; virtual; stdcall; abstract;
    Function READ_SAMPLE(Channel : WORD; Sample : pSHORT) : boolean; virtual; stdcall; abstract;
    Function ReadData(lpBuffer : pSHORT; nNumberOfWordsToRead, lpNumberOfBytesRead : pDWORD; lpOverlapped : POverlapped) : boolean; virtual; stdcall; abstract;
 
    // функции для работы в режиме вывода данных
    Function GET_OUTPUT_PARS(dp : pOUTPUT_PARS_USB3000) : boolean; virtual; stdcall; abstract;
    Function SET_OUTPUT_PARS(dp : pOUTPUT_PARS_USB3000) : boolean; virtual; stdcall; abstract;
    Function START_WRITE : boolean; virtual; stdcall; abstract;
    Function STOP_WRITE : boolean; virtual; stdcall; abstract;
    Function WRITE_SAMPLE(Channel : WORD; Sample : pSHORT) : boolean; virtual; stdcall; abstract;
    Function WriteData(lpBuffer : pSHORT; nNumberOfWordsToWrite, lpNumberOfBytesWritten : pDWORD; lpOverlapped : POverlapped) : boolean; virtual; stdcall; abstract;
 
    // функции для работы с ТТЛ линиями
    Function ENABLE_TTL_OUT(EnabledTtlOut : boolean) : boolean; virtual; stdcall; abstract;
    Function TTL_OUT(TtlOut : WORD) : boolean; virtual; stdcall; abstract;
    Function TTL_IN(TtlIn : pWORD) : boolean; virtual; stdcall; abstract;
 
    // функции для работы ППЗУ
    Function ENABLE_FLASH_WRITE(EnableFlashWrite : boolean) : boolean; virtual; stdcall; abstract;
    Function PUT_FLASH(fi : pFLASH_USB3000) : boolean; virtual; stdcall; abstract;
    Function GET_FLASH(fi : pFLASH_USB3000) : boolean; virtual; stdcall; abstract;
 
    // функция выдачи строки с последней ошибкой
    Function GetLastErrorString(lpBuffer : pCHAR; nSize : DWORD) : Integer; virtual; stdcall; abstract;
end;
PIRTUSB3000 = ^IRTUSB3000;
 
const
// текущая версия библиотеки Rtusbapi.dll
    VERMAJOR_RTUSBAPI           =   $0001;
    VERMINOR_RTUSBAPI           =   $0005;
    CURRENT_VERSION_RTUSBAPI    =   ((VERMAJOR_RTUSBAPI shl 16) or VERMINOR_RTUSBAPI);
 
// объявление экспортируемых из Rtusbapi.dll функций
Function RtGetDllVersion : DWORD; stdcall;
Function RtCreateInstance(DeviceName : PChar) : Pointer; stdcall;
 
implementation
    Function RtGetDllVersion : DWORD; External 'Rtusbapi.dll'
    Function RtCreateInstance(DeviceName : PChar) : Pointer; External 'Rtusbapi.dll'
end.
Вызываются эти функции так:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
var
    // версия библиотеки Rtusbapi.dll
    DllVersion : DWORD;
 
    // интерфейс модуля USB3000
    pModule : IRTUSB3000;
begin
    // проверим версию используемой DLL библиотеки
    DllVersion := RtGetDllVersion; // <-- тут всё понятно
    if DllVersion <> CURRENT_VERSION_RTUSBAPI then
        begin
            ErrorString := 'Неверная версия DLL библиотеки Rtusbapi.dll! ' + #10#13 +
                        '           Текущая: ' + IntToStr(DllVersion shr 16) +  '.' + IntToStr(DllVersion and $FFFF) + '.' +
                        ' Требуется: ' + IntToStr(CURRENT_VERSION_RTUSBAPI shr 16) + '.' + IntToStr(CURRENT_VERSION_RTUSBAPI and $FFFF) + '.';
            TerminateApplication(ErrorString);
        end
    else WriteLn(' DLL Version --> OK');
 
    // попробуем получить указатель на интерфейс для модуля USB3000
    pModule := RtCreateInstance(pCHAR('usb3000')); // <-- а тут на Delphi тоже всё выглядит просто
    if pModule = nil then TerminateApplication('Не могу найти интерфейс модуля USB3000!')
    else WriteLn(' Module Interface --> OK');
 
    // попробуем обнаружить модуль USB3000 в первых 127 виртуальных слотах
    for i := 0 to 126 do
    if pModule.OpenDevice(i) then break; 
 
// и т.д.
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
09.11.2016, 08:53
Ответы с готовыми решениями:

Использование функций, возвращающих указатель на указатель
Здравствуйте. Есть несколько функций, которые возвращают указатель на указатель. Вот одна из них: long ZGetBufferADC(long...

Как правильно передать и получить указатель из нативной библиотеки?
Есть некий Сишный код (я опускаю __delc и прочее) с C# я абсолютно не знаком struct Block { int s }

Вызов функций из DLL на С++
В программе:using System; using System.Collections.Generic; using System.Linq; using System.Text; using...

33
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,574
18.11.2016, 17:06
Студворк — интернет-сервис помощи студентам
Как же с вами сложно, почему вы не можете сделать все именно так как написано мной в 5 посте (без всяких ссылок)? Инфа по ссылке актуальна только если нет виртуальных функций (у вас они ЕСТЬ!)...

Добавлено через 25 минут
Проверил еще раз, скопипастив из вашего кода полный список виртуальных фвнкций, все работает...

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
    struct IRTUSB3000Test
    {
        public IntPtr vtable;
        // поля...
    }
 
    struct IRTUSB3000TestVTable
    {
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool OpenDeviceDelegate(IntPtr self, ushort VirtualSlot);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool CloseDeviceDelegate(IntPtr self);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate long GetModuleHandleDelegate(IntPtr self);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool GetUsbSpeedDelegate(IntPtr self, byte UsbSpeed);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool GetModuleNameDelegate(IntPtr self, string ModuleName);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool GetModuleSerialNumberDelegate(IntPtr self, string SerialNumber);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool GetAvrVersionDelegate(IntPtr self, string AvrVersion);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool ReleaseInstanceDelegate(IntPtr self);
 
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool RESET_DSPDelegate(IntPtr self);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool LOAD_DSPDelegate(IntPtr self, string FileName);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool MODULE_TESTDelegate(IntPtr self);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool GET_DSP_INFODelegate(IntPtr self, DSP_INFO_USB3000 DspInfo);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool SEND_COMMANDDelegate(IntPtr self, ushort Command);
 
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool PUT_VAR_WORDDelegate(IntPtr self, ushort Address, short Data);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool GET_VAR_WORDDelegate(IntPtr self, ushort Address, short Data);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool PUT_DM_WORDDelegate(IntPtr self, ushort Address, short Data);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool GET_DM_WORDDelegate(IntPtr self, ushort Address, short Data);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool PUT_PM_WORDDelegate(IntPtr self, ushort Address, int Data);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool GET_PM_WORDDelegate(IntPtr self, ushort Address, int Data);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool PUT_DM_ARRAYDelegate(IntPtr self, ushort BaseAddress, ushort NPoints, short Data);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool GET_DM_ARRAYDelegate(IntPtr self, ushort BaseAddress, ushort NPoints, short Data);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool PUT_PM_ARRAYDelegate(IntPtr self, ushort BaseAddress, ushort NPoints, int Data);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool GET_PM_ARRAYDelegate(IntPtr self, ushort BaseAddress, ushort NPoints, int Data);
 
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool GET_INPUT_PARSDelegate(IntPtr self, INPUT_PARS_USB3000 ap);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool SET_INPUT_PARSDelegate(IntPtr self, INPUT_PARS_USB3000 ap);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool START_READDelegate(IntPtr self);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool STOP_READDelegate(IntPtr self);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool READ_KADRDelegate(IntPtr self, short Data);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool READ_SAMPLEDelegate(IntPtr self, ushort Channel, short Sample);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool ReadDataDelegate(IntPtr self, short lpBuffer, uint nNumberOfWordsToRead, uint lpNumberOfBytesRead, Overlapped lpOverlapped);
 
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool GET_OUTPUT_PARSDelegate(IntPtr self, OUTPUT_PARS_USB3000 dp);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool SET_OUTPUT_PARSDelegate(IntPtr self, OUTPUT_PARS_USB3000 dp);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool START_WRITEDelegate(IntPtr self);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool STOP_WRITEDelegate(IntPtr self);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool WRITE_SAMPLEDelegate(IntPtr self, ushort Channel, short Sample);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool WriteDataDelegate(short lpBuffer, uint nNumberOfWordsToWrite, uint lpNumberOfBytesWritten, Overlapped lpOverlapped);
 
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool ENABLE_TTL_OUTDelegate(IntPtr self, bool EnabledTtlOut);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool TTL_OUTDelegate(IntPtr self, ushort TtlOut);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool TTL_INDelegate(IntPtr self, ushort TtlIn);
 
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool ENABLE_FLASH_WRITEDelegate(IntPtr self, bool EnableFlashWrite);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool PUT_FLASHDelegate(IntPtr self, FLASH_USB3000 fi);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool GET_FLASHDelegate(IntPtr self, FLASH_USB3000 fi);
 
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate int GetLastErrorStringDelegate(IntPtr self, string lpBuffer, int nSize);
 
        public OpenDeviceDelegate OpenDevice;
        public CloseDeviceDelegate CloseDevice;
        public GetModuleHandleDelegate GetModuleHandle;
        public GetUsbSpeedDelegate GetUsbSpeed;
        public GetModuleNameDelegate GetModuleName;
        public GetModuleSerialNumberDelegate GetModuleSerialNumber;
        public GetAvrVersionDelegate GetAvrVersion;
        public ReleaseInstanceDelegate ReleaseInstance;
 
        public RESET_DSPDelegate RESET_DSP;
        public LOAD_DSPDelegate LOAD_DSP;
        public MODULE_TESTDelegate MODULE_TEST;
        public GET_DSP_INFODelegate GET_DSP_INFO;
        public SEND_COMMANDDelegate SEND_COMMAND;
 
        public PUT_VAR_WORDDelegate PUT_VAR_WORD;
        public GET_VAR_WORDDelegate GET_VAR_WORD;
        public PUT_DM_WORDDelegate PUT_DM_WORD;
        public GET_DM_WORDDelegate GET_DM_WORD;
        public PUT_PM_WORDDelegate PUT_PM_WORD;
        public GET_PM_WORDDelegate GET_PM_WORD;
        public PUT_DM_ARRAYDelegate PUT_DM_ARRAY;
        public GET_DM_ARRAYDelegate GET_DM_ARRAY;
        public PUT_PM_ARRAYDelegate PUT_PM_ARRAY;
        public GET_PM_ARRAYDelegate GET_PM_ARRAY;
 
        public GET_INPUT_PARSDelegate GET_INPUT_PARS;
        public SET_INPUT_PARSDelegate SET_INPUT_PARS;
        public START_READDelegate START_READ;
        public STOP_READDelegate STOP_READ;
        public READ_KADRDelegate READ_KADR;
        public READ_SAMPLEDelegate READ_SAMPLE;
        public ReadDataDelegate ReadData;
 
        public GET_OUTPUT_PARSDelegate GET_OUTPUT_PARS;
        public SET_OUTPUT_PARSDelegate SET_OUTPUT_PARS;
        public START_WRITEDelegate START_WRITE;
        public STOP_WRITEDelegate STOP_WRITE;
        public WRITE_SAMPLEDelegate WRITE_SAMPLE;
        public WriteDataDelegate WriteData;
 
        public ENABLE_TTL_OUTDelegate ENABLE_TTL_OUT;
        public TTL_OUTDelegate TTL_OUT;
        public TTL_INDelegate TTL_IN;
 
        public ENABLE_FLASH_WRITEDelegate ENABLE_FLASH_WRITE;
        public PUT_FLASHDelegate PUT_FLASH;
        public GET_FLASHDelegate GET_FLASH;
 
        public GetLastErrorStringDelegate GetLastErrorString;
    }
C#
1
2
3
4
5
6
7
8
9
            IntPtr structPtr = Rtusbapi.RtCreateInstance("usb3000");
 
            IRTUSB3000Test pModule = (IRTUSB3000Test)Marshal.PtrToStructure(structPtr, typeof(IRTUSB3000Test));
 
            IRTUSB3000TestVTable vt = (IRTUSB3000TestVTable)Marshal.PtrToStructure(pModule.vtable, typeof(IRTUSB3000TestVTable));
 
            bool result = vt.OpenDevice(structPtr, 0);
 
            vt.CloseDevice(structPtr);
0
1 / 1 / 0
Регистрация: 04.09.2014
Сообщений: 21
18.11.2016, 17:48  [ТС]
Я дико извиняюсь, и я понимаю, что мне тут никто ничего не должен, но если бы вы не писали загадками, может и не было со мной так сложно.

C#
1
2
3
4
5
    struct IRTUSB3000Test
    {
        public IntPtr vtable;
        // поля...
    }
Я спросил, что за поля. Вы мне ответили
Цитата Сообщение от Someone007 Посмотреть сообщение
Поля вложенной структуры RTUSB3000::DSP_INFO. Вы хоть смотрели как объявлена структура в С++?
Я так понял это (в конвертированном варианте)
C#
1
2
3
4
5
6
7
8
9
10
11
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct DSP_INFO_USB3000                          // size = 18 
    {
        public IntPtr vtable;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
        public byte[] Target;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
        public byte[] DrvLabel;
        public byte DspMajor;
        public byte DspMinor;
    }
Где, в таком случае, остальные структуры? (ну ок, по аналогии сделаю)
Каким образом получается pModule отсюда:
C#
1
IRTUSB3000Test pModule = (IRTUSB3000Test)Marshal.PtrToStructure(structPtr, typeof(IRTUSB3000Test));
если из RtCreateInstance получается structPtr - возвращает указатель на "основную" структуру IRTUSB3000TestVTable, никак не IRTUSB3000Test?

Я просто логику никак не пойму, не судите строго.
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,574
18.11.2016, 18:00
Цитата Сообщение от Selya Посмотреть сообщение
Я так понял это (в конвертированном варианте)
Да.

Цитата Сообщение от Selya Посмотреть сообщение
Где, в таком случае, остальные структуры?
Какие остальные? Там больше ничего помоему нет. Может я что-то конечно проглядел...

Цитата Сообщение от Selya Посмотреть сообщение
если из RtCreateInstance получается structPtr - возвращает указатель на "основную" структуру IRTUSB3000TestVTable, никак не IRTUSB3000Test?
Неверно. Возвращается именно указатель на IRTUSB3000Test, а не на IRTUSB3000TestVTable. Указатель на IRTUSB3000TestVTable находится в первом поле структуры IRTUSB3000Test.
0
1 / 1 / 0
Регистрация: 04.09.2014
Сообщений: 21
18.11.2016, 18:08  [ТС]
Цитата Сообщение от Someone007 Посмотреть сообщение
Возвращается именно указатель на IRTUSB3000Test
В таком случае IRTUSB3000Test это не DSP_INFO_USB3000, а IRTUSB3000 в моём первоначальном варианте (из поста 2) с дополнительным полем public IntPtr vtable;
И эту структуру надо как-то наверно по особому объявлять, abstruct или что-то в этом роде, не знаю. Чтобы методы OpenDevice, CloseDevice и т.д. не реализовывать.
(сейчас попробую)
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,574
18.11.2016, 18:15
Цитата Сообщение от Selya Посмотреть сообщение
В таком случае IRTUSB3000Test это не DSP_INFO_USB3000
Конечно нет, она просто содержит в себе DSP_INFO_USB3000.

C#
1
2
3
4
5
struct IRTUSB3000Test
{
    public IntPtr vtable;
    public DSP_INFO_USB3000 blabla;
}
или так

C#
1
2
3
4
5
6
7
8
9
10
struct IRTUSB3000Test
{
        public IntPtr vtable;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
        public byte[] Target;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
        public byte[] DrvLabel;
        public byte DspMajor;
        public byte DspMinor;
}
Цитата Сообщение от Selya Посмотреть сообщение
И эту структуру надо как-то наверно по особому объявлять, abstruct или что-то в этом роде, не знаю.
Ненадо. Просто скопируйте мой код наконец...
0
1 / 1 / 0
Регистрация: 04.09.2014
Сообщений: 21
18.11.2016, 18:32  [ТС]
Цитата Сообщение от Someone007 Посмотреть сообщение
Просто скопируйте мой код наконец...
Не могу) DSP_INFO_USB3000 это "не основная" структура. Основная это IRTUSB3000 и RtCreateInstance возвращает указатель на неё. Посмотрите заголовочный файл.
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,574
18.11.2016, 18:36
Цитата Сообщение от Selya Посмотреть сообщение
Не могу) DSP_INFO_USB3000 это "не основная" структура. Основная это IRTUSB3000 и RtCreateInstance возвращает указатель на неё.
Все верно. Проблема то в чем я не пойму?
0
1 / 1 / 0
Регистрация: 04.09.2014
Сообщений: 21
18.11.2016, 18:44  [ТС]
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
    public struct IRTUSB3000
    {
        public IntPtr vtable;
        // USB интерфейс модуля
        public extern bool OpenDevice(ushort VirtualSlot);
        public extern bool CloseDevice();
        public extern long GetModuleHandle();
        public extern bool GetUsbSpeed(byte UsbSpeed);
        public extern bool GetModuleName(string ModuleName);
        public extern bool GetModuleSerialNumber(string SerialNumber);
        public extern bool GetAvrVersion(string AvrVersion);
        public extern bool ReleaseInstance();
// ...
    }
    struct IRTUSB3000VTable
    {
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool OpenDeviceDelegate(IntPtr self, ushort VirtualSlot);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool CloseDeviceDelegate(IntPtr self);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate long GetModuleHandleDelegate(IntPtr self);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool GetUsbSpeedDelegate(IntPtr self, byte UsbSpeed);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool GetModuleNameDelegate(IntPtr self, string ModuleName);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool GetModuleSerialNumberDelegate(IntPtr self, string SerialNumber);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool GetAvrVersionDelegate(IntPtr self, string AvrVersion);
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate bool ReleaseInstanceDelegate(IntPtr self);
// ...
 
        public OpenDeviceDelegate OpenDevice;
        public CloseDeviceDelegate CloseDevice;
        public GetModuleHandleDelegate GetModuleHandle;
        public GetUsbSpeedDelegate GetUsbSpeed;
        public GetModuleNameDelegate GetModuleName;
        public GetModuleSerialNumberDelegate GetModuleSerialNumber;
        public GetAvrVersionDelegate GetAvrVersion;
        public ReleaseInstanceDelegate ReleaseInstance;
// ...
 
    }
C#
1
2
3
4
5
6
7
8
9
            IntPtr structPtr = USB3000.RtCreateInstance("usb3000");
 
            IRTUSB3000 pModule = (IRTUSB3000)Marshal.PtrToStructure(structPtr, typeof(IRTUSB3000));
 
            IRTUSB3000VTable vt = (IRTUSB3000VTable)Marshal.PtrToStructure(pModule.vtable, typeof(IRTUSB3000VTable));
 
            bool result = vt.OpenDevice(structPtr, 0);
 
            vt.CloseDevice(structPtr);
Вот как-то так? Но если это так, то ещё на этапе компиляции вылетает
TypeLoadException was unhandled
Не удалось загрузить тип "Rtusbapi.IRTUSB3000" из сборки "DynLoadCS, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null", так как метод "OpenDevice" не имеет реализации (не имеет RVA).
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,574
18.11.2016, 18:51
Нет не так, зачем вы опять в IRTUSB3000 напихали методов? Нет их там...

Добавлено через 1 минуту
Вас вообще несмущает что в vtable и в самой структуре одинаковые методы?
0
1 / 1 / 0
Регистрация: 04.09.2014
Сообщений: 21
18.11.2016, 18:59  [ТС]
Конечно смущает. И ещё смущает, что вы в именно к DSP_INFO_USB3000 привязываетесь. Там же и другие такие же структуры есть: INPUT_PARS_USB3000, OUTPUT_PARS_USB3000, FLASH_USB3000. И основная структура это IRTUSB3000
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,574
18.11.2016, 19:07
Цитата Сообщение от Selya Посмотреть сообщение
И ещё смущает, что вы в именно к DSP_INFO_USB3000 привязываетесь.
Я к ней1 не привязываюсь.

Цитата Сообщение от Selya Посмотреть сообщение
Там же и другие такие же структуры есть: INPUT_PARS_USB3000, OUTPUT_PARS_USB3000, FLASH_USB3000.
Они тут вообще не причем. Это отдельные структуры вообще никак не связанные с темой топика.

Цитата Сообщение от Selya Посмотреть сообщение
И основная структура это IRTUSB3000
Я где-то сказал что это не так?

Короче возьмите мой код (посты #5, #21), запустите его, а затем уже задавайте вопросы. Методом тыка тут ничего не получится.
0
1 / 1 / 0
Регистрация: 04.09.2014
Сообщений: 21
21.11.2016, 08:18  [ТС]
Цитата Сообщение от Someone007 Посмотреть сообщение
Проверил еще раз, скопипастив из вашего кода полный список виртуальных фвнкций, все работает...
Не знаю, что у вас там работает. Может компилируется, но не работает. Не может RtCreateInstance возвращать указатель на структуру DSP_INFO_USB3000 (в вашем случае IRTUSB3000Test, тем более с дополнительным полем public IntPtr vtable

Как вы верно заметили, ни INPUT_PARS_USB3000, OUTPUT_PARS_USB3000, FLASH_USB3000, ни DSP_INFO_USB3000 здесь абсолютно не причём.

RtCreateInstance возвращает указатель на интерфейс IRTUSB3000

В исходнике dll-ки Rtusbapi.cpp так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//------------------------------------------------------------------------
// создание экземпляра необходимого класса
//------------------------------------------------------------------------
extern "C" LPVOID WINAPI RtCreateInstance(PCHAR const DeviceName)
{
    WORD DevNameLength;
    char DevName[MAX_DEVICE_NAME_LENGTH + 1];       // название устройства не более 17 символов
                                                                // включая null-terminating character
    LPVOID pDevice = NULL;
 
    // причешем название модуля
    DevNameLength = (WORD)strlen(DeviceName);
    if(!DevNameLength) return NULL;
    else if(DevNameLength > MAX_DEVICE_NAME_LENGTH) DevNameLength = MAX_DEVICE_NAME_LENGTH;
    strncpy(DevName, DeviceName, DevNameLength);
    DevName[DevNameLength] = '\0';
 
    // попробуем открыть интерфейс на требуемый модуль
    if(!strcmpi(DevName, "USBDETECT")) pDevice = static_cast<IRTUSBDETECT *>(new CRTUSBDETECT(hInstance));
    else if(!strcmpi(DevName, "USB2185")) pDevice = static_cast<IRTUSB2185 *>(new CRTUSB2185(hInstance));
    else if(!strcmpi(DevName, "USB3000")) pDevice = static_cast<IRTUSB3000 *>(new CRTUSB3000(hInstance));
    // что-то не так с названием устройства
    return pDevice;
}
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,574
21.11.2016, 13:16
RtCreateInstance возвращает указатель на структуру, которую я уже неоднократно постил в этом топике (да, она отличается от того, что было в исходом коде в виду наличия виртуальных функций). Если она вас почему-то не устраивает и вам даже лень запустить мой код, то это ваши личные проблемы. Вместо этого вы продолжаете говорить что код не работает, и даже не можете сказать что именно не работает...
0
1 / 1 / 0
Регистрация: 04.09.2014
Сообщений: 21
21.11.2016, 14:11  [ТС]
Прошу прощения за свою тугость, но да. Ваш код из поста #5 действительно работает.
Более того, я оставил только одно поле
C#
1
2
3
4
5
6
7
8
9
10
struct IRTUSB3000Test
{
        public IntPtr vtable;
//        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
//        public byte[] Target;
//        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
//        public byte[] DrvLabel;
//        public byte DspMajor;
//        public byte DspMinor;
}
Всё равно работает (по крайней мере vt.OpenDevice). Теперь буду проверять, правильно работает или нет.

Спасибо за помощь.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
21.11.2016, 14:11
Помогаю со студенческими работами здесь

Использование функций, возвращающих одно значение
помогите решить: Использование функций, возвращающих одно значение. Даны целочисленные массивы D, A. Для каждого массива определить...

Подключение нативной dll к проекту
Создал C# проект консольный. В одном решении с ним создал win32 пустой проект, указал,что проект пустой и его считать dll библиотекой....

Вызов функций из DLL, написанной на CBuilder.
Всем привет! Есть немаленький софт, написанный на CBuilder. Нужно подгрузить в программе на C# готовые бибилиотеки. Нашел, что с...

Вызов из Python функций сторонней DLL
Подскажите пожалуйста по такому вопросу. Нужно из Python вызвать функцию из сторонней DLL. Проблема в том, как передать параметры, которые...

Экспорт функций из dll на c++ и вызов из Delphi
Вызываю экспортируемую функцию из dll которая написана на c++. Вызываю из Delphi, с вызовом проблем нет но когда оно принимает мою строку...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
34
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru