我有一个整整一周都在挣扎的问题,我无法自己解决。我一直在闲逛,并在各种论坛中进行搜索...我发现很多“可行的方法”,都尝试过,但是没有成功。如果有人有任何线索,请帮助我!

我从外部获得了很多用VB编写的类和函数,我需要这些类和函数可以在C++应用程序中使用。我的第一个想法是:没问题,我将VB代码转换为dll,并从我的C++程序中加载了它。尽管这比我想象的要难。我的C++程序不是用Visual Studio编写的,但是为了简单起见,我首先尝试从Visual Studio C++应用程序加载VB dll(用Visual Studio 2010编写)。到目前为止,这是我的代码:

VB代码:DllModule:类库项目

DllModule.vb

Namespace DllModule
  Public Module DllModule

    Public Const DLL_PROCESS_DETACH = 0
    Public Const DLL_PROCESS_ATTACH = 1
    Public Const DLL_THREAD_ATTACH = 2
    Public Const DLL_THREAD_DETACH = 3

    Public Function DllMain(ByVal hInst As Long, ByVal fdwReason As Long,
      ByVal lpvReserved As Long) As Boolean
        Select Case fdwReason
            Case DLL_PROCESS_DETACH
                ' No per-process cleanup needed
            Case DLL_PROCESS_ATTACH
                DllMain = True
            Case DLL_THREAD_ATTACH
                ' No per-thread initialization needed
            Case DLL_THREAD_DETACH
                ' No per-thread cleanup needed
        End Select

        Return True
    End Function

    'Simple function
    Public Function Add(ByVal first As Integer, ByVal sec As Integer) As Integer
        Dim abc As Integer
        abc = first + sec
        Return abc
    End Function
  End Module
End Namespace

DllModule.def
NAME DllModule
LIBRARY DllModule
DESCRIPTION "My dll"
EXPORTS DllMain @1
        Add @2

C++代码:TryVbDllLoad:控制台应用程序

TryVbDllLoad.cpp
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <strsafe.h>

extern "C" {
 __declspec(dllimport) int __stdcall Add(int, int);
}

typedef int (__stdcall *ptf_test_func_1_type)(int, int);

int __cdecl _tmain(int argc, _TCHAR* argv[])
{
    HINSTANCE hdll = NULL;

    hdll = LoadLibrary("DllModule.dll");        // load the dll
    if(hdll) {
        ptf_test_func_1_type p_func1=(ptf_test_func_1_type)GetProcAddress(hdll,"Add");

        if(p_func1) {
           int ret_val = (*p_func1)(1, 2);
        } else {
        DWORD dw = GetLastError();
        }

        FreeLibrary(hdll);              // free the dll
    } else {
        DWORD dw = GetLastError();
    }

    return 0;
}

我可以加载dll,但是GetProcAddess返回NULL,错误代码为127(找不到指定的过程)。

我试图从VB应用程序加载dll。这可以工作(即使没有.def文件)。但是我猜测没有创建C++应用程序可以使用的适当入口点(当我在Dependency Walker中打开dll时,我看不到任何入口点或函数)。我尝试使用和不使用“注册COM互操作”来编译VB代码。

1)我做错了什么?

2)如果没有解决此问题的好方法,该怎么办而不是创建dll?我可以在C++应用程序中使用VB类和函数吗?

亲切的问候

莎拉



谢谢您的回答,母马!

我的dll中肯定存在某种错误,原因是当我尝试使用regsvr32进行注册时,我得到:“模块C:/tmp/DllModule.dll已加载,但未找到DllRegisterServer的起始地址。检查是否C:/tmp/DllModule.dll是有效的DLL或OCX文件,然后重试。”

另外,当我使用
#import "C\tmp\DllModule.dll"
我懂了
fatal error C1083: Cannot open type library file: 'c:\tmp\dllmodule.dll'
我看了本教程的链接,但是有一个小问题:在所有项目类型中都没有“ActiveX DLL”之类的东西可供选择。是的,我确实有Visual Studio 2010 Professional(试用版,但仍然有)。

-萨拉

最佳答案

感谢所有的投入。我遇到了另一种解决问题的方法,使用多文件程序集而不是我的第一个dll方法。

我遵循此HowTo部分:http://msdn.microsoft.com/en-us/library/226t7yxe.aspx#Y749

VB代码:DllModule:类库项目

DllModule.vb

Imports System.Runtime.InteropServices

Namespace DllModuleNS
    Public Class Class1

        Public Function ClassAdd(ByRef first As Integer, ByRef sec As Integer) As Integer
            Dim abc As Integer
            abc = first + sec
            Return abc
        End Function

    End Class
End Namespace

我同时使用Visual Studio(生成DllModule.dll文件)和cmd-line编译了此文件:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\Vbc.exe /t:module DllModule.vb

(以生成DllModule.netmodule文件)。

C++代码:TryVbDllLoad:控制台应用程序

TryVbDllLoad.cpp
#using <mscorlib.dll>

#using ".\..\ClassLibrary1\DllModule.netmodule"
using namespace DllModule::DllModuleNS;

int _tmain(int argc, _TCHAR* argv[])
{
    Class1^ me = gcnew Class1();
    int a = 1, b = 2;
    int xx = me->ClassAdd(a, b);
    return 0;
}

在TryVBDllLoad-project属性中,我进行了更改:
  • 通用属性->框架和引用:添加了DllModule-project作为引用
  • 配置属性-> C / C++->常规:/ clr标志设置
  • 配置属性->链接器->输入:将模块添加到程序集设置为DllModule.netmodule的路径(/ASSEMBLYMODULE:"DllModule.netmodule“)

  • 这导致我可以在VC++代码中使用VB类Class1!

    问题解决了!

    现在,我将其更进一步,并将TryVBDllLoad-project更改为dll:
  • 配置属性->常规:Configurationtype动态库(.dll)
  • 配置属性->链接器->系统:子系统Windows(/ SUBSYSTEM:WINDOWS)

  • TryVbDllLoadClass.h
    #ifndef TryVbDllLoadClass_H
    #define TryVbDllLoadClass_H
    
    class TryVbDllLoadClass
    {
    public:
        TryVbDllLoadClass();
        int Add(int a, int b);
    };
    
    #endif  // TryVbDllLoadClass_H
    

    TryVbDllLoadClass.cpp
    #include "TryVbDllLoadClass.h"
    #using <mscorlib.dll>
    
    #using ".\..\ClassLibrary1\DllModule.netmodule"
    using namespace DllModule::DllModuleNS;
    
    
    TryVbDllLoadClass::TryVbDllLoadClass() {}
    
    int TryVbDllLoadClass::Add(int a, int b)
    {
    Class1^ me = gcnew Class1();
    int xx = me->ClassAdd(a, b);
    return xx;
    }
    

    DllExport.h
    #ifndef DLLEXPORT_H
    #define DLLEXPORT_H
    
    #define WIN32_LEAN_AND_MEAN
    #include <Windows.h>
    
    #ifdef __dll__
    #define IMPEXP __declspec(dllexport)
    #else
    #define IMPEXP __declspec(dllimport)
    #endif  // __dll__
    
    extern "C" {
        IMPEXP int __stdcall AddFunction(int);
    }
    
    #endif  // DLLEXPORT_H
    

    DllMain.h
    #define __dll__
    #include "dllExport.h"
    #include " TryVbDllLoadClass.h"
    
    int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*)
    {
        return 1;
    }
    
    TryVbDllLoadClass * my;
    
    IMPEXP int __stdcall AddFunction(int first, int second)
    {
        my = new TryVbDllLoadClass();
        int res = my->Add(first, second);
        delete my;
        return res;
    }
    

    然后,可以像普通的dll一样将此dll添加到非可视工作室项目中:

    C++代码:LoadDll:非Visual Studio项目(在这种情况下为CodeBlocks)

    main.cpp
    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #define WIN32_LEAN_AND_MEAN
    #include <windows.h>
    
    #include "dllExport.h"
    
    typedef int( * LPFNDLL_CREATE)(int, int);
    HINSTANCE hDLL;
    LPFNDLL_CREATE func;
    
    using namespace std;
    
    int main()
    {
        cout << "Hello world!" << endl;
        int key = 35;
    
        hDLL = LoadLibrary("TryVbDllLoadClass.dll");
    
        if(hDLL)
        {
            cout << "Loaded: " << hDLL << endl;
    
            func = (LPFNDLL_CREATE) (GetProcAddress(hDLL, "_AddFunction@4"));
            if(func != NULL)
            {
                cout << "Connected: " << func << endl;
                cout << "Function returns: " << func(key, key) << endl;
            }
            else cout << " ::: fail: " << GetLastError() << endl;
    
            FreeLibrary(hDLL);
            cout << "Freed" << endl;
        }
        else cout << " ::: fail: " << GetLastError() << endl;
    
        printf("-> Goodbye world!\n");
        return 0;
    }
    

    这样,我就可以在Visuabl Studio外部创建的现有C++项目中使用给我的VB类。最后...:)

    08-16 20:25