我将函数从C ++ DLL导入C#应用程序。我能够导入和一些功能,但不能导入其他功能。 C ++ DLL附带了一个C ++项目,该项目展示了如何从C ++中使用它。我想在C#中复制它,但我在编组方面遇到了麻烦。这是C ++:
标头文件声明:
unsigned long __stdcall mfcs_initialisation(unsigned short serial);
unsigned long __stdcall mfcsez_initialisation(unsigned short serial);
unsigned char __stdcall mfcs_close(unsigned long handle);
unsigned char __stdcall mfcs_set_purge_on(unsigned long int handle);
unsigned char __stdcall mfcs_set_purge_off(unsigned long int handle);
unsigned char __stdcall mfcs_get_purge(unsigned long int handle,
unsigned char * c);
unsigned char __stdcall mfcs_get_status(
unsigned long int handle,
unsigned char * c);
unsigned char __stdcall mfcs_read_chan(
unsigned long int handle,
unsigned char canal,
float * pressure,
unsigned short * chrono);
unsigned char __stdcall mfcs_data_chan(
unsigned long int handle,
unsigned char canal,
unsigned char * unite,
unsigned short * max,
unsigned short * zero,
unsigned short * mesure,
unsigned short * chrono);
unsigned char __stdcall mfcs_get_serial(unsigned long int handle,
unsigned short * us);
unsigned char __stdcall mfcs_set_auto(
unsigned long int handle,
unsigned char canal,
float pcons);
unsigned char __stdcall mfcs_set_alpha(
unsigned long int handle,
unsigned char canal,
unsigned char alpha);
unsigned char __stdcall mfcs_set_manual(
unsigned long int handle,
unsigned char canal,
float pcons);
unsigned char __stdcall mfcs_set_zero(
unsigned long int handle,
unsigned char canal,
unsigned short zero);
unsigned char __stdcall mfcs_detect(unsigned short table[256]);
unsigned char __stdcall mfcsez_detect(unsigned short table[256]);
C ++代码:
/* Define functions prototype */
typedef unsigned long(__stdcall *init)(int);
typedef unsigned char(__stdcall *purgeOn)(unsigned long handle);
typedef unsigned char(__stdcall *purgeOff)(unsigned long handle);
typedef unsigned char(__stdcall *serial)(unsigned long handle, unsigned short *serial);
typedef unsigned char(__stdcall *close)(unsigned long handle);
typedef unsigned char(__stdcall *setAuto)(unsigned long int handle, unsigned
char canal, float pcons);
typedef unsigned char(__stdcall *readChannel)(unsigned long handle, unsigned
char chan, float * pressure, unsigned short * chrono);
typedef unsigned char(__stdcall *setAlpha)(unsigned long int handle, unsigned
char canal, unsigned char alpha);
int main(int argc, char *argv[])
{
/* System settings variable definition */
float start_pressure = 70; //Pressure set (mbar) at the beginning
float target_pressure = 100; //Maximal pressure setpoint (mbar)
unsigned char pressureChannel = 1; //Selected channel (0 for all channels or put the channel number you would like to control)
HINSTANCE hGetProcIDDLL=NULL; // Define dll handler
/* Load DLL into memory */
hGetProcIDDLL = LoadLibrary(TEXT("mfcs_c.dll"));
/* Declare pointers on dll functions */
init dll_init;
purgeOn dll_purgeOn;
purgeOff dll_purgeOff;
serial dll_serial;
close dll_close;
setAuto dll_setAuto;
readChannel dll_readChannel;
setAlpha dll_setAlpha;
/* Link dll pointers with functions prototype */
dll_init = (init)GetProcAddress(hGetProcIDDLL, "mfcsez_initialisation");
dll_serial = (serial)GetProcAddress(hGetProcIDDLL, "mfcs_get_serial");
dll_purgeOn = (purgeOn)GetProcAddress(hGetProcIDDLL, "mfcs_set_purge_on");
dll_purgeOff = (purgeOff)GetProcAddress(hGetProcIDDLL, "mfcs_set_purge_off");
dll_close = (close)GetProcAddress(hGetProcIDDLL, "mfcs_close");
dll_setAuto = (setAuto)GetProcAddress(hGetProcIDDLL, "mfcs_set_auto");
dll_readChannel = (readChannel)GetProcAddress(hGetProcIDDLL, "mfcs_read_chan");
dll_setAlpha = (setAlpha)GetProcAddress(hGetProcIDDLL, "mfcs_set_alpha");
/* Define variables used for MFCS device */
unsigned long mfcsHandle;
unsigned short mySerial;
float read_pressure;
unsigned short chrono;
int loop_index;
if (hGetProcIDDLL != NULL) { // If dll loaded
std::cout << "mfcs_c.dll is loaded" << std::endl;
/* Initialize device */
if (dll_init != NULL) { // Check if function was properly linked to the dll file
/* Initialize the first MFCS in Windows enumeration list */
mfcsHandle = dll_init(0);
/* After the initialization we need to add a delay of 500ms to make sure that the USB communication is properly established */
Sleep(500);
std::cout << "MFCS initialized" << std::endl;
}
/* Read device serial number */
if (dll_serial != NULL) {
/*Get the serial number of the MFCS*/
dll_serial(mfcsHandle, &mySerial);
std::cout << "MFCS SN: " << mySerial << std::endl;
}
/* Set pressure regulation servitude coefficient */
if (dll_setAlpha != NULL) {
dll_setAlpha(mfcsHandle ,pressureChannel, 4); // Default value (just after power on) is 0
} // Alpha value has to be grather than 0 in order to regulate pressure
/* Change and read pressure every second until reaching 'target_pressure' value */
for (loop_index = int(start_pressure); loop_index<target_pressure; loop_index++){
dll_setAuto(mfcsHandle,pressureChannel,float(loop_index)); // Set required output pressure value
Sleep(1000); // Wait 1 s
dll_readChannel(mfcsHandle, pressureChannel, &read_pressure, &chrono); // Get the pressure value on the specified channel
std::cout << "Set pressure at: " << loop_index << "mbar" << "; Read pressure: " << read_pressure
<< "mbar" << std::endl; // Display pressure setpoint and channel pressure value
}
/* Close MFCS session */
if (dll_close != NULL) {
dll_close(mfcsHandle);
std::cout << "MFCS closed" << std::endl;
}
}
/* Release the DLL */
FreeLibrary(hGetProcIDDLL);
std::cout << "mfcs_c.dll unloaded" << std::endl;
/* Exit application */
system("PAUSE");
return EXIT_SUCCESS;
}
基本上我已尝试过许多导入函数的排列,以及任何包含无符号字符或指针的函数,我无法弄清楚如何映射。
非常感谢大卫推动我从我的生活中变得更有用。
注意:有助于我的一个例子是基于上面的C ++代码的明确指令,用于引入mfcs_get_serial(unsigned long int句柄, 无符号短*序列)到C#。
答案 0 :(得分:0)
请注意,此答案是针对问题的原始版本编写的,然后才会将其编辑为其他问题。我不是冒着编辑战争的风险,而是按原样离开。
在Windows上的C ++ long
是32位类型。所以
unsigned long __stdcall mfcs_initialisation(unsigned short serial);
应该是
[DllImport("mfcs_c_64.dll", CallingConvention = CallingConvention.StdCall)]
public static extern uint mfcs_initialisation(ushort serial);
根据提供的信息,其他功能更难翻译。第二个参数可以是单个值,也可以是数组。前者更有可能。所以翻译应该是
[DllImport("mfcs_c_64.dll", CallingConvention = CallingConvention.StdCall)]
public static extern byte mfcs_get_serial(uint handle, out ushort us);