2016-09-22 2 views
0

Мне нужно вызвать функцию из C++ Dll (BVRelate.dll) через Visual Basic (VBWpf).Как вызвать C++ DLL-функцию из VB?

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 (проект МОФ)

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). Так что я положил файл четкости в каталоге с длл файл, а также с файлами 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. Это не сработало. Появилось одно и то же исключение. Дамббин вернул ту же свалку, ничего не изменилось.

+1

Программа с Option Strict On на некоторое время так компилятор? может рассказать вам о такой простой ошибке. Это Sub, а не функция. –

+0

Я включил эту опцию, thanx. Я попытался объявить функцию DoSomething Lib «M: \ VBRelate.dll»() как объект, а также объявить Sub DoSomething Lib «M: \ VBRelate.dll»(). Та же проблема –

+0

Добавление extern «C» в объявление функции dll и определение заставляют ее работать. –

ответ

0

Проблема не в пределах кода DLL/родного C++, хотя, возможно, если вы сделали это управляемой C++ dll? Исключение говорит что-то неладно с обработкой данных между управляемым (VB) и неуправляемого (C++) Код: MarshalDirectiveException on MSDN

Это может быть возможным, чтобы изменить атрибуты, используя MarshalAsAttribute()msdn

+0

Не поймите ... какие атрибуты я должен маршал? Функция является недействительной и не имеет аргументов ... void DoSomething() –

+0

Возможно, что-то не так с именем функции? Как я читал, это должно быть не так? DoSomething @@ YAXXZ = @ ILT + 660 (? DoSomething @@ YAXXZ) в дампе –

+1

Добавление extern «C» в декларации и определении функции dll заставило ее работать. –

0

решаемые

Добавление extern «C» в объявление функции dll и определение заставляют ее работать.

//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

Смежные вопросы