2016-09-22 133 views
0

我需要通過Visual Basic(VBWpf)從C++ Dll(BVRelate.dll)調用函數。如何從VB調用C++ DLL函數?

C++的dll代碼:

//VBRelate.h 

#ifdef VBRELATE_EXPORTS 
#define VBRELATE_API __declspec(dllexport) 
#else 
#define VBRELATE_API __declspec(dllimport) 
#endif 

extern VBRELATE_API void DoSomething(); 

//VBRelate.cpp 

#include <atlstr.h> 
#include "VBRelate.h" 

VBRELATE_API void DoSomething() 
{ 
    CString strOutput("Hello world"); 
    MessageBox(NULL, strOutput, L"Got a message", MB_OK); 
} 

然後我嘗試從VB(WPF項目)

Imports System.Runtime.InteropServices 
Class MainWindow 
    Declare Function DoSomething Lib "M:\VBRelate.dll"() 
    Private Sub button_Click(sender As Object, e As RoutedEventArgs) Handles button.Click 
     DoSomething() 
    End Sub 
End Class 

調用這個函數,而且我得到了一個例外:

「MarshalDirectiveException了未處理」 。類型 'System.Runtime.InteropServices.MarshalDirectiveException' 未處理的異常發生在VBWpf.exe

然後我用DUMPBIN:

dumpbin /exports "M:\VBRelate.dll">M:\VBRelate.txt 

和VBRelate.txt是這樣的:

Microsoft (R) COFF/PE Dumper Version 10.00.40219.01 
Copyright (C) Microsoft Corporation. All rights reserved. 


Dump of file M:\VBRelate.dll 

File Type: DLL 

    Section contains the following exports for VBRelate.dll 

    00000000 characteristics 
    57E3DDA6 time date stamp Thu Sep 22 16:33:26 2016 
     0.00 version 
      1 ordinal base 
      1 number of functions 
      1 number of names 

    ordinal hint RVA  name 

      1 0 00011299 [email protected]@YAXXZ = @ILT+660([email protected]@YAXXZ) 

    Summary 

     1000 .00cfg 
     4000 .data 
     1000 .gfids 
     1000 .idata 
     4000 .rdata 
     1000 .reloc 
     1000 .rsrc 
     10000 .text 
     10000 .textbss 
     1000 .tls 

然後我試圖使用def文件,但並不真正完全理解如何使用它(應該在哪裏 - 與dll文件,項目文件或其他地方),爲什麼我應該在使用__declspec(而不是__stdcall)時使用它。所以我把DEF文件與DLL文件的目錄,同時還與DLL文件的項目:

; VBRelate.def - defines the exports for VBRelate.dll 

LIBRARY VBRelate.dll 
DESCRIPTION 'A C++ dll that can be called from VB' 

EXPORTS 
    DoSomething 

然後我重建DLL。 它沒有工作。同樣的例外出現了。並且dumpbin返回了相同的轉儲,沒有任何更改。

+1

計劃與選項嚴格了一會兒所以編譯器?可以告訴你這樣一個簡單的錯誤。它是一個子,而不是一個功能。 –

+0

我開啓了這個選項,thanx。我試着聲明函數DoSomething Lib「M:\ VBRelate.dll」()作爲對象,並聲明Sub DoSomething Lib「M:\ VBRelate.dll」()。同樣的問題 –

+0

在dll函數聲明和定義中添加extern「C」使它工作。 –

回答

0

該問題似乎不在DLL /本機C++代碼中,但是如果您將其作爲託管C++ dll?唯一的例外是說有什麼問題管理(VB)之間處理數據和非託管(C++)代碼:MarshalDirectiveException on MSDN

它可能會使用MarshalAsAttribute()msdn

+0

不要低頭......我應該編組哪些屬性?該函數是無效類型,並沒有參數... void DoSomething() –

+0

也許有函數名稱有問題嗎?當我讀它應該不是這樣嗎?DoSomething @@ YAXXZ = @ ILT + 660(?DoSomething @@ YAXXZ)在轉儲 –

+1

在dll函數聲明和定義中添加extern「C」使它工作。 –

0

解決

更改屬性

在dll函數聲明和定義中添加extern「C」使其工作。

//VBRelate.h 
#ifdef VBRELATE_EXPORTS 
#define VBRELATE_API __declspec(dllexport) 
#else 
#define VBRELATE_API __declspec(dllimport) 
#endif 

extern "C" VBRELATE_API void DoSomething(); 

//VBRelate.cpp 
extern "C" 
{ 
    VBRELATE_API void DoSomething() 
    { 
     CString strOutput("Hello world"); 
     MessageBox(NULL, strOutput, L"Got a message", MB_OK); 
    } 
} 

所以我認爲問題是在裝飾名稱。添加外部的「C」後,轉儲文件是這樣的:

Microsoft (R) COFF/PE Dumper Version 10.00.40219.01 
Copyright (C) Microsoft Corporation. All rights reserved. 


Dump of file M:\VBRelate.dll 

File Type: DLL 

    Section contains the following exports for VBRelate.dll 

    00000000 characteristics 
    57E52794 time date stamp Fri Sep 23 16:01:08 2016 
     0.00 version 
      1 ordinal base 
      1 number of functions 
      1 number of names 

    ordinal hint RVA  name 

      1 0 000112C1 DoSomething = @ILT+700(_DoSomething) 

    Summary 

     1000 .00cfg 
     4000 .data 
     1000 .gfids 
     1000 .idata 
     4000 .rdata 
     1000 .reloc 
     1000 .rsrc 
     10000 .text 
     10000 .textbss 
     1000 .tls 

因此函數名稱現在是正確的,但它的DoSomething @@ YAXXZ