2014-12-03 115 views
1

我有第三方.dll,我必須在C++/CLI代碼中使用它的函數。我想dllimport的,但我收到一個錯誤:Dllimport函數返回結構

錯誤C33385:「msp_FormatMessage」:具有dllimport的定製attribite不能返回類

的一個實例,在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

您應該標記'C++/CLI'這樣的問題,很多環視'C++'標籤的人甚至不知道它存在,所以在詢問時應該明確說明它 – PeterT 2014-12-04 00:28:37

+0

您確定結果是直接返回而不是指針? – svick 2014-12-05 01:27:55

+0

[我能找到的唯一'msp_FormatMessage](http://www.module.ru/upload/files/2604_rtl2gsw.pdf#page=47)確實如此:'msp_Message * msp_FormatMessage( msp_Message * buffer, msp_BYTE類型, msp_BYTE RT, msp_BYTE SA, msp_BYTE RTR_MC, msp_WORD SAR_MCD, msp_BYTE dataWordCount, msp_WORD *數據, msp_DWORD bccw);' – svick 2014-12-05 01:34:29

回答

0

不明白的問題..顯示的代碼。顯示錯誤消息..我剛剛測試了dllimport的結構..

您應該注意,通過dlopen和dlsym或loadlibrary和getprocaddress的動態加載通常是首選。爲什麼?因爲你不能「總是」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

+0

呀,提問者沒有充分解釋,他實際使用' C++/CLI特定的'[DLLImport]'結構。但我想你的問題仍然是相關的,如果他希望它在純粹的C++工作 – PeterT 2014-12-04 00:37:49

+0

是的,你是對的,我使用的是C++/CLI。我已經編輯了這個問題來說清楚。 – AndrewR 2014-12-04 09:54:12

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,"[email protected]@[email protected]@[email protected]@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; 
} 

名稱[email protected]@[email protected]@[email protected]@Z是,你可以通過在運行DUMPBIN /EXPORTS drtl3.dll得到什麼visual studio命令行。也可能只是C鏈接,這會使名稱更小。

+1

不,它仍然會導致相同的錯誤 – AndrewR 2014-12-04 09:50:03

+0

@ maniac98066好,我添加了不那麼漂亮的C++方法(也適用於CLI)。我不是CLI專家,所以我不能用'DllImport'幫助你 – PeterT 2014-12-04 11:49:25