我有第三方.dll,我必须在C ++ / CLI代码中使用它的功能。我试图扼杀它,但我收到一个错误:
错误C33385:' msp_FormatMessage':具有Dllimport自定义属性的函数无法返回类的实例
在C#中,这个问题可以通过使用StructLayout来解决,但我找不到任何方法来解决C ++ / CLI中的这个问题。
功能定义:
[DllImport("drtl3.dll", EntryPoint = "msp_FormatMessage")]
extern "C++" msp_Message msp_FormatMessage(msp_Message* buffer, char type, char RT, char SA, char RTR_MC, unsigned short SAR_MCD, char dataWordCount, unsigned short data[], unsigned int bccw);
结构定义:
typedef struct {
msp_WORD type;
msp_WORD dataWordCount;
msp_WORD bccw;
msp_WORD CmdWord1;
msp_WORD CmdWord2;
msp_WORD Data[32];
msp_WORD StatusWord1;
msp_WORD StatusWord2;
msp_WORD loopback;
msp_WORD bsw;
msp_WORD timetag;
msp_BYTE present;
msp_BYTE transmit;
msp_BYTE check;
msp_BYTE role;
} msp_Message;
答案 0 :(得分:1)
你需要声明它作为非托管返回的结构,这样可以正常工作:
#using <mscorlib.dll>
using namespace System::Runtime::InteropServices;
#pragma managed(push, off)
using msp_WORD = short;
using msp_BYTE = char;
typedef struct {
msp_WORD type;
msp_WORD dataWordCount;
msp_WORD bccw;
msp_WORD CmdWord1;
msp_WORD CmdWord2;
msp_WORD Data[32];
msp_WORD StatusWord1;
msp_WORD StatusWord2;
msp_WORD loopback;
msp_WORD bsw;
msp_WORD timetag;
msp_BYTE present;
msp_BYTE transmit;
msp_BYTE check;
msp_BYTE role;
} msp_Message;
#pragma managed(pop)
[DllImport("drtl3.dll", EntryPoint = "msp_FormatMessage")]
extern "C++" msp_Message msp_FormatMessage(msp_Message* buffer, char type, char RT, char SA, char RTR_MC, unsigned short SAR_MCD, char dataWordCount, unsigned short data [], unsigned int bccw);
或者如果这不起作用,你总是可以用C ++的方式来做,这也适用于C ++ / CLI
#include "windows.h"
#pragma managed(push, off)
using msp_WORD = short;
using msp_BYTE = char;
typedef struct {
msp_WORD type;
msp_WORD dataWordCount;
msp_WORD bccw;
msp_WORD CmdWord1;
msp_WORD CmdWord2;
msp_WORD Data[32];
msp_WORD StatusWord1;
msp_WORD StatusWord2;
msp_WORD loopback;
msp_WORD bsw;
msp_WORD timetag;
msp_BYTE present;
msp_BYTE transmit;
msp_BYTE check;
msp_BYTE role;
} msp_Message;
#pragma managed(pop)
typedef msp_Message msp_FormatMessage_t(msp_Message* buffer, char type, char RT, char SA, char RTR_MC, unsigned short SAR_MCD, char dataWordCount, unsigned short data [], unsigned int bccw);
msp_FormatMessage_t *msp_FormatMessage;
HINSTANCE hDLL;
int main(array<System::String ^> ^args)
{
hDLL= LoadLibraryA("drtl3.dll");
msp_FormatMessage = (msp_FormatMessage_t *)GetProcAddress(hDLL,"?msp_FormatMessage@@YA?AUmsp_Message_t@@PAU1@DDDDGDQAGI@Z");
msp_Message test = msp_FormatMessage(nullptr, 1, 2, 3, 4, 5, 6, nullptr, 7);
Console::Write("type ");
Console::WriteLine(test.type);
Console::Write("check");
Console::WriteLine(test.check);
// std::cout << "type" << test.type << std::endl;
//std::cout << "check" << test.check << std::endl;
Console::WriteLine(L"Hello World");
return 0;
}
通过在visual studio命令行中运行?msp_FormatMessage@@YA?AUmsp_Message_t@@PAU1@DDDDGDQAGI@Z
,可以获得名称DUMPBIN /EXPORTS drtl3.dll
。也可能只是C链接,这会使名称变小。
答案 1 :(得分:0)
不要理解这个问题..显示代码。显示错误消息..我刚用结构测试了dllimport ..
您应该注意,通过dlopen和dlsym或loadlibrary和getprocaddress进行动态加载通常是首选。为什么?因为你不能总是&#34; dllimport的。示例:带有VS2012的dllexport在g ++中并不总是与dllimport一起使用。对于如何导出符号没有明确的标准。
使用Mingw-g ++ 4.8.1
DLL:
#include <windows.h>
#include <cstring>
typedef struct {
unsigned short meh;
unsigned short bleh;
char we[50];
} foo;
extern __declspec(dllexport) foo some_func()
{
foo f;
f.meh = 10;
f.bleh = 20;
strcpy(f.we, "hello world\0");
return f;
}
extern "C" __declspec(dllexport) BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
进口商:
#include <iostream>
typedef struct {
unsigned short meh;
unsigned short bleh;
char we[50];
} foo;
extern __declspec(dllimport) foo some_func();
int main()
{
foo f = some_func();
std::cout<<f.meh<<" "<<f.bleh<<" "<<f.we<<"\n";
return 0;
}
结果:10 20 hello world