制作 VB-dll 并将其加载到 C++ 应用程序中

2024-02-04

我有一个问题已经困扰了整整一周,但我自己无法解决。我一直在谷歌搜索,并在各种论坛中搜索......我发现了很多“这可能有用”,尝试过,但没有,没有成功。如果有人有任何线索,请帮助我!

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

VB 代码:DllModule:类库项目

DllModule.cs

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 类和函数?

亲切的问候

Sara



谢谢马雷的回答!

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

另外,当我使用

#import "C\tmp\DllModule.dll"

I get

fatal error C1083: Cannot open type library file: 'c:\tmp\dllmodule.dll'


我查看了教程的链接,但有一个小问题:在所有项目类型中没有“ActiveX DLL”之类的东西可供选择。是的,我确实有 Visual Studio 2010 Professional(试用版,但仍然是)。

-- Sara


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

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

VB 代码:DllModule:类库项目

DllModule.cs

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 行编译此文件:

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 项目属性中:

  • 通用属性 -> 框架和参考:添加 DllModule-project 作为参考
  • 配置属性 -> C/C++ -> 常规:/clr 标志设置
  • 配置属性 -> 链接器 -> 输入:将模块添加到程序集设置为 DllModule.netmodule 的路径(/ASSEMBLYMODULE:"DllModule.netmodule")

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

问题解决了!


现在我更进一步,将 TryVBDllLoad 项目更改为 dll:

  • 配置属性 -> 常规:配置类型动态库 (.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;
}

DLL导出.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 添加到非 Visual Studio 项目中:

C++ 代码:LoadDll:非 Visual-Studio 项目(本例中为 CodeBlock)

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 类。最后...:)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

制作 VB-dll 并将其加载到 C++ 应用程序中 的相关文章

随机推荐

  • 计算子集的唯一交集

    Given a set S si zj z N what is a time efficient algorithm for computing the unique sets of intersections of the subsets
  • Ivy:使用动态修订

    我在理解如何使用动态修订版时遇到问题Ivy http ant apache org ivy 在我的 Java 项目中有效 目前 我有以下布局 lib a revision 1 0 0 status release dependencies
  • Powershell启动作业同步输出

    我有一个启动作业的 powershell 脚本 start job scriptblock while true echo Running Start Sleep 2 然后它继续执行脚本的其余部分 该工作是一种对该进程 PID 的监控工作
  • Apache 用户帐户无密码访问服务器 - Ubuntu

    我有同样的问题this https stackoverflow com questions 9089350 rsync via php exec with ssh passwordless ssh login问题 如果我再解释一遍 我可以使
  • 前向声明类成员的前向声明

    是否可以前向声明一个在另一个前向声明的类中声明的类 基本上 我有这样的东西 A h class A struct B 现在我想声明另一个这样的类 Q h class A struct A B class Q A B Foo 不 这是不可能的
  • 在 WordPress 中获取类别 ID 数组?

    cats get categories array order gt ASC orderby gt id hierarchical gt 0 hide empty gt 0 taxonomy gt edu year 我想生成一个变量 其中包
  • 当作为 *.a 静态库链接时,为什么“WinMain”无法解析?

    给定一个简单的程序 include
  • 如何将 PHPUnit 与 CodeIgniter 结合使用?

    我读过并阅读过有关 PHPUnit SimpleTest 和其他单元测试框架的文章 他们听起来都很棒 我终于让 PHPUnit 与 Codeigniter 一起工作了 感谢https bitbucket org kenjis my ciun
  • 默认模板参数在部分特化上下文中的作用

    我不清楚部分专业化背景下默认模板参数的交互 以选择哪个是更好的匹配模板 这个问题源于此中发布的代码answer https stackoverflow com questions 52565407 use of enable if to m
  • Jenkins Slave 问题 - 无效的流标头:099EACED

    Jenkins 2 7 4 安装在 RedHat 服务器中 并且通过选择 通过在主服务器上执行命令来启动代理 选项来配置 Linux 从站 我们创建了一个 Shell 脚本 它在 Jenkins 版本 2 7 4 中运行良好 现在我们将 J
  • “这个”阴影是个好主意吗?

    隐藏类变量的情况在 Java 中很常见 Eclipse 将愉快地生成以下代码 public class TestClass private int value private String test public TestClass int
  • 将数据库设置从 application.ini 中取出并放入环境中

    在基于 Zend 的应用程序的传统编码中 数据库设置存储在 application ini 中 这会存储每个应用程序的设置 StackOverflow 上是否有人探索过将数据库设置从 application ini 移动到环境中的可能性 例
  • Picasso 库无法在 Android 上从 SD 卡加载图像

    我从图像库的路径中获取一个文件 并尝试将其加载到图像视图 如下所示 文件路径为 storage sdcard0 DCIM Camera 1436267579864 jpg 我也尝试传递 Uri 我也有 SD 卡的读取权限 它最终在onErr
  • 如何通过IP获取时区[重复]

    这个问题在这里已经有答案了 我有一个注册 通过它我可以获得注册用户的IP地址 我想通过用户的 IP 地址获取用户的时区 就像在 jquery 中我们可以得到这样的结果jquery 中的时区 http pellepim bitbucket o
  • 如何获取 .NET 中的资源监视器值?

    我需要获取 Windows 7 资源监视器中的一些值 特别是每个进程的内存使用情况 CPU 和带宽 我研究了 PerformanceCounter 类 但没有找到深入到进程级别的方法 资源监视器正是我正在寻找的东西 在你问之前 我知道这是重
  • raise StopIteration 和生成器中的 return 语句有什么区别?

    我很好奇使用之间的区别raise StopIteration and a return生成器中的语句 例如 这两个函数有什么区别吗 def my generator0 n for i in range n yield i if i gt 5
  • 安装 pydev 时出错[重复]

    这个问题在这里已经有答案了 我安装了 eclipse 3 7 并且想从 help gt install new software 从 pydev org updates 安装 pydev 但我不断收到错误 An error occurred
  • Python描述符与属性[重复]

    这个问题在这里已经有答案了 我对何时使用属性和描述符感到困惑 我读到属性是一个专门的描述符 有人可以发布这是如何工作的吗 您应该阅读有关描述符实际是什么的文档 Cliff s Notes 版本 描述符是一种低级机制 可让您挂钩正在访问的对象
  • Rails 5 资产未在生产中加载

    我最近更新了 Rails 应用程序中的一些软件包 但现在我的资产无法提供服务 相反 我收到以下错误 Failed to load resource the server responded with a status of 404 Not
  • 制作 VB-dll 并将其加载到 C++ 应用程序中

    我有一个问题已经困扰了整整一周 但我自己无法解决 我一直在谷歌搜索 并在各种论坛中搜索 我发现了很多 这可能有用 尝试过 但没有 没有成功 如果有人有任何线索 请帮助我 我从外部源获得了许多用 VB 编写的类和函数 我需要能够在 C 应用程