返回struct的Dllimport函数

时间:2014-12-03 23:44:43

标签: struct c++-cli dllimport

我有第三方.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;

2 个答案:

答案 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