Есть dll написаная на с++. Необходмо испльзовать ее в с#. heder c++
//---------------------------------------------------------------------------
#ifndef CRZUSBH
#define CRZUSBH
//---------------------------------------------------------------------------
#ifdef CRZUSB_EXPORTS
#define CRZUSB_API extern "C" __declspec(dllexport)
#else
#define CRZUSB_API extern "C" __declspec(dllimport)
#endif
//---------------------------------------------------------------------------
#define SIZE_MATR_ADDR_RECV 512
#define MAX_COUNT_RZ_DATA 128
#define MAX_COUNT_CHANNELS 16
#define FREQ_RZ_GET_DEVICE 0x00
#define FREQ_RZ_12and5kHz 0x01
#define FREQ_RZ_50kHZ 0x02
#define FREQ_RZ_100kHZ 0x03
#define FREQ_RZ_UNKNOWN 0xFF
#define FORMAT_RZ_DOP 0x00
#define FORMAT_RZ_OSN 0x01
#define CTRL_PARR_PARITY 0x00
#define CTRL_PARR_ODDNESS 0x01
#define IDDEV_2RZTOUSB 0x01
#define ENABLE_ADDR_REC 0x01
#define DISABLE_ADDR_REC 0x00
//---------------------------------------------------------------------------
//#pragma pack(show)
#pragma pack(push,1)
//#pragma pack(show)
struct sInitDevice
{
unsigned char ucFreqRZ;
unsigned char ucFormatRZ;
unsigned char ucCtrlParr;
unsigned char ucAddrRecv;
unsigned char pucMatrAddrRecv[SIZE_MATR_ADDR_RECV];
};
struct sInitDeviceEx
{
struct sInitChannel
{
BYTE FreqRZ;
BYTE FormatRZ;
BYTE CtrlParr;
} ParamChannel[MAX_COUNT_CHANNELS];
BYTE AddrRecv;
BYTE MatrAddrRecv[SIZE_MATR_ADDR_RECV];
};
struct sInfoDevice
{
bool bCorrectInfo;
unsigned char ucCodeErrorDevice;
unsigned char ucIDDevice;
unsigned char ucFreqRZ;
unsigned char ucCountChannels;
unsigned short usDensityRZ;
unsigned short usPlantNum;
unsigned short usNumPO;
unsigned short usVersionPO;
};
struct sInfoDeviceEx
{
bool bCorrectInfo;
BYTE CodeErrorDevice;
BYTE IDDevice;
WORD NumPO;
WORD VersionPO;
WORD PlantNum;
BYTE CountChannels;
struct sInfoChannel
{
BYTE FreqRZ;
WORD DensityRZ;
} InfoChannel[MAX_COUNT_CHANNELS];
};
struct sRZStream
{
unsigned char CountRZMessage;
unsigned short CountTrashRZMessage;
unsigned short CountMissingRZMessage;
bool IsMissingRZMessage;
struct
{
unsigned char Address;
unsigned char Low;
unsigned char High;
unsigned char Additional;
unsigned char Channel;
} RZ_DATA[MAX_COUNT_RZ_DATA];
//Index RZ_DATA: [0 ... (CountRZMessage - 1)]
};
struct sRZStreamEx
{
struct
{
union
{
struct
{
BYTE Low;
BYTE High;
BYTE Additional;
BYTE Address;
};
DWORD RzMessage;
};
} RZ_DATA[MAX_COUNT_RZ_DATA];
struct
{
BYTE Channel_0 : 4;
BYTE Channel_1 : 4;
} CHANNELS[MAX_COUNT_RZ_DATA / 2];
BYTE System00;
BYTE CountRZMessage;
union
{
struct
{
BYTE CountTrashRZMessageL;
BYTE CountTrashRZMessageH;
};
WORD CountTrashRZMessage;
};
BYTE IsMissingRZMessage;
union
{
struct
{
BYTE CountMissingRZMessageL;
BYTE CountMissingRZMessageH;
};
WORD CountMissingRZMessage;
};
BYTE System07;
BYTE System08;
BYTE System09;
BYTE System10;
BYTE System11;
BYTE System12;
BYTE System13;
BYTE System14;
BYTE System15;
inline BYTE GetChannelRZMessage (int IndexRZMessage)
{
return (IndexRZMessage & 0x01) ? CHANNELS[IndexRZMessage >> 1].Channel_1 : CHANNELS[IndexRZMessage >> 1].Channel_0;
}
};
struct sRZTimingData
{
BYTE Data[MAX_COUNT_RZ_DATA];
};
#pragma pack(pop)
//#pragma pack(show)
//---------------------------------------------------------------------------
CRZUSB_API bool RzUsb_ConnectDevice (void);
CRZUSB_API bool RzUsb_IsConnectToDevice (void);
CRZUSB_API bool RzUsb_DisconnectDevice (void);
CRZUSB_API bool RzUsb_InitDevice (sInitDevice*, sInfoDevice*);
CRZUSB_API bool RzUsb_InitDeviceEx (sInitDeviceEx*, sInfoDeviceEx*);
CRZUSB_API void RzUsb_SetReadTimeout (unsigned long);
CRZUSB_API void RzUsb_SetWriteTimeout (unsigned long);
CRZUSB_API bool RzUsb_RunReceiveRZ (void);
CRZUSB_API bool RzUsb_StopReceiveRZ (void);
CRZUSB_API bool RzUsb_ReceiveRZStream (sRZStream*);
CRZUSB_API bool RzUsb_ReceiveRZStreamEx (sRZStreamEx*);
CRZUSB_API bool RzUsb_IsReceiveRZStream (void);
//--------------------SUPPORT TIMING DATA------------------------------------
CRZUSB_API bool RzUsb_IsSupportTimingData (void);
CRZUSB_API bool RzUsb_GetTimingData (sRZTimingData*);
//---------------------------------------------------------------------------
#endif
//---------------------------------------------------------------------------
Как преобразовать структуры для с#?
Это как бы смешивание управляемого и нативного кода. В данном случае в C# хорошо интегрируются COM объекты. Поэтому одним из способов интеграции является создание обвязки в виде COM объекта. В этом случае данные dll можно преобразовать в данные, понятные в управляемом коде.
Еще одним способом (мне нравится больше) является использование C++ CLR. Для этого создается проект типа Class Library и в нем CLR класс который будет управлять нативным dll. Здесь тоже придется данные преобразовывать, но это можно сделать в виде тех же CLR объектов.
Ниже я написал небольшой код для примера. Я в нем загружаю библиотеку работы с сокетом.
#pragma once
#include "windows.h"
#include <atlstr.h>
using namespace System;
namespace NativeClasses {
public ref class AddrIn
{
public:
int Port;
String^ sAddr;
};
public ref class NativeSocket
{
u_short (*htons)(u_short);
unsigned long (*inet_addr)(const char*);
public:
NativeSocket(void)
{
HMODULE hm = LoadLibrary (L"ws2_32.dll");
if ( hm )
{
SOCKET (*socket)(int,int,int) = (SOCKET (*)(int,int,int)) GetProcAddress(hm, "socket");
int (*closesocket)(SOCKET) = (int (*)(SOCKET)) GetProcAddress(hm, "socket");
htons = (u_short (*)(u_short)) GetProcAddress(hm, "htons");
inet_addr = (unsigned long (*)(const char*)) GetProcAddress(hm, "inet_addr");
SOCKET s = (*socket) (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (s)
(*closesocket) (s);
FreeLibrary(hm);
}
}
void SetAddr( AddrIn^ Addr )
{
sockaddr_in addr = {0};
addr.sin_family = AF_INET;
addr.sin_port = (*htons)(Addr->Port);
CString sAddr(Addr->sAddr);
CW2A asAddr(sAddr);
addr.sin_addr.S_un.S_addr = (*inet_addr)(asAddr);
}
};
}
Сборку с классами затем включается в ссылки проекта на C# и может использоваться обычным вызовом:
NativeClasses.NativeSocket s = new NativeClasses.NativeSocket();
NativeClasses.AddrIn addr = new NativeClasses.AddrIn() ;
addr.Port = 1000;
addr.sAddr = "10.1.0.100";
s.SetAddr(addr);
Для преобразования строк на мой взгляд удобнее всего использовать ATL. Остальное на усмотрение.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Конфиг: Windows Server 2016, x64, 1Гб ОЗУ Создал службу по мануалу Размещение ASPNET Core в службе Windows установил на дом
Есть кусок кода,написанный в python, с помощью api йобита выводит цену по определенной паре
В личном кабинете пользователь может создать список своих делРеализация может показаться вам глупой, но мне интересно ваше мнение по поводу...