如何在不通过 COM 的情况下从 VB6 调用 C++ DLL? [英] How to call a C++ DLL from VB6 without going through COM?
问题描述
好的,所以我有一个编译成 DLL 文件的 C++ 项目.我能够在 C# 中引用此文件并查看/使用 DLL 文件中的所有对象和函数.我需要做的是通过VB6引用这些对象和函数.
C++ 代码中没有任何看起来像是在创建 DLL 的内容.没有 '__declspec(dllexport)' 修饰符,只有 C++ 代码.
有这样的对象:
字符串^数组^
我不完全确定它们是什么.我对 C++ 的了解不是很广泛,而且我只用 C++ 为 Linux 系统编写过代码,尽管从使用上看,它们有点像指针.这些对象与 C++ 中的 DLL 有什么关系吗?
无论如何,我可以添加任何我需要的包装器或添加一个定义文件 (.def),尽管我不知道要使用什么包装器,也不知道定义文件是如何工作的或需要如何构建.
感谢任何帮助和/或建议.如果您也可以向我推荐一些好的信息,那将很有帮助.我所做的所有搜索都没有帮助.
记住,我需要从 VB6 访问这个 C++ DLL 中的所有函数和对象.
谢谢.
向问题添加了 .h 文件和 AssemblyInfo.cpp 规范
我更改了这些文件中的一些名称,但结构是相同的.请注意,这引用了其他文件,但我假设如果可以使一个文件工作,那么其他文件可以使用相同的过程.我可以看到每个对象,只是看不到方法:
//myDBObject.h#pragma once使用命名空间系统;命名空间 myDBNamespace {#include "问题解决方案.h"公共引用类 MyDataBaseAccessor{民众:MyDataBaseAccessor();静态字符串 ^ GetServiceVersion() { 返回 sDLLVersion;};int GetServiceStatus() { return myiDBStatus;};字符串 ^ GetMyVersion();字符串 ^ GetDBVersion();字符串 ^ GetDLLVersion();字符串 ^ GetExpireDate();MyOtherObject ^ GetMyOtherObject();int ProcessProblem(ProblemSolution ^ dsps);私人的:静态 MyDataBaseController ^ myDataBase;静态 MyOtherObject ^ myObjs;静态 MyDataset ^ myDS;静态字符串 ^ myDBPath;静态字符串 ^ sDLLVersion = "0.01";静态字符串 ^ sReqDBVer = "0.01";静态 int myiDBStatus;static bool myBoolean, myOtherBoolean, mybNoChain;};}
这是 AssemblyInfo.cpp 文件:
#include "stdafx.h"使用命名空间系统;使用命名空间 System::Reflection;使用命名空间 System::Runtime::CompilerServices;使用命名空间 System::Runtime::InteropServices;使用命名空间 System::Security::Permissions;////关于程序集的一般信息是通过以下方式控制的//属性集.更改这些属性值以修改信息//与程序集相关联.//[assembly:AssemblyTitleAttribute("我的产品标题")];[程序集:AssemblyDescriptionAttribute("")];[装配:AssemblyConfigurationAttribute("")];[assembly:AssemblyCompanyAttribute("我的公司")];[assembly:AssemblyProductAttribute("我的产品名称")];[程序集:AssemblyCopyrightAttribute("我的版权")];[程序集:AssemblyTrademarkAttribute("我的程序")];[装配:AssemblyCultureAttribute("")];////程序集的版本信息由以下四个值组成:////主要版本//次要版本//内部编号// 修订////您可以指定所有值,也可以默认版本号和内部版本号//通过使用*",如下所示:[程序集:AssemblyVersionAttribute("1.0.*")];[程序集:ComVisible(真)];//这里是ComVisible标签.这是假的,我把它设置为真[程序集:CLSCompliantAttribute(true)];[程序集:SecurityPermission(SecurityAction::RequestMinimum, UnmanagedCode = false)];
使用 regasm 从您的 C++/CLI 程序集创建 COM 类型库 (.TLB) 文件.
您现在应该能够通过在 VB6 代码中引用 TLB 文件来引用 C++/CLI 代码.从那里的例子:
<块引用>以最简单的形式,您可以:
REGASM MyAssembly.dll
现在,所有的注册 COM 兼容的类作为 COM 对象.你可以启动VB6并开始编写代码:
Dim net As ObjectSet obj = CreateObject("NETProject.Foo")对象移动
<块引用>
很简单.除了你迟到绑定,因为你没有 COM类型库.
没问题!REGASM 可以生成一个类型库,甚至可以注册它:
REGASM MyAssembly.dll/tlb:MyAssembly.tlb
现在,在 VB6 中,您可以添加对类型库并尽早使用绑定:
Dim net As Foo设置 obj = New NETProject.Foo对象移动
像这样使类 COM 可见:
[ComVisible(true)]公共引用类 MyDataBaseAccessor
OK, so I have a C++ project that compiles to a DLL file. I am able to reference this file in C# and see/use all of the objects and functions within the DLL file. What I need to do is to reference those objects and function through VB6.
The C++ code has nothing in it that looks like it's creating a DLL. There are no '__declspec(dllexport)' modifiers, just C++ code.
There are objects like this:
String ^
Array^
I'm not entirely sure what they are. My knowledge of C++ is not very extensive and I've only coded in C++ for Linux systems, although from the usage they sort of look like pointers. Do these objects have anything to do with a DLL in C++?
Anyway, I can add any wrappers that I need or add a definition file (.def), although I do not know what wrappers to use and I don't know how a definition file works or how it needs to be constructed.
Any help and/or suggestions are appreciated. If you can refer me to some good info as well, that would be helpful. All searching I have done has not helped.
Remember, I need to access all functions and objects in this C++ DLL from VB6.
Thanks.
EDIT: Added .h file and AssemblyInfo.cpp spec to the question
I changed some names in these files, but the structure is the same. Note that this references other files, but I assume that if one can be made to work then the others can with the same process. I can see every object, just not the methods:
//myDBObject.h
#pragma once
using namespace System;
namespace myDBNamespace {
#include "ProblemSolution.h"
public ref class MyDataBaseAccessor
{
public:
MyDataBaseAccessor();
static String ^ GetServiceVersion() { return sDLLVersion;};
int GetServiceStatus() { return myiDBStatus;};
String ^ GetMyVersion();
String ^ GetDBVersion();
String ^ GetDLLVersion();
String ^ GetExpireDate();
MyOtherObject ^ GetMyOtherObject();
int ProcessProblem(ProblemSolution ^ dsps);
private:
static MyDataBaseController ^ myDataBase;
static MyOtherObject ^ myObjs;
static MyDataset ^ myDS;
static String ^ myDBPath;
static String ^ sDLLVersion = "0.01";
static String ^ sReqDBVer = "0.01";
static int myiDBStatus;
static bool myBoolean, myOtherBoolean, mybNoChain;
};
}
Here is the AssemblyInfo.cpp file:
#include "stdafx.h"
using namespace System;
using namespace System::Reflection;
using namespace System::Runtime::CompilerServices;
using namespace System::Runtime::InteropServices;
using namespace System::Security::Permissions;
//
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
//
[assembly:AssemblyTitleAttribute("My Product Title")];
[assembly:AssemblyDescriptionAttribute("")];
[assembly:AssemblyConfigurationAttribute("")];
[assembly:AssemblyCompanyAttribute("My Company")];
[assembly:AssemblyProductAttribute("My Product Name")];
[assembly:AssemblyCopyrightAttribute("My Copyright")];
[assembly:AssemblyTrademarkAttribute("My Program")];
[assembly:AssemblyCultureAttribute("")];
//
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the value or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly:AssemblyVersionAttribute("1.0.*")];
[assembly:ComVisible(true)]; //Here is the ComVisible tag. It was false and I set it to true
[assembly:CLSCompliantAttribute(true)];
[assembly:SecurityPermission(SecurityAction::RequestMinimum, UnmanagedCode = false)];
Use regasm to create a COM Type Library (.TLB) file from your C++/CLI assembly.
You should now be able to reference the C++/CLI code by referencing the TLB file in your VB6 code. From the example there:
In its simplest form, you can do:
REGASM MyAssembly.dll
Now, all of the COM-compatible classes are registered as COM objects. You can fire up VB6 and start writing code:
Dim net As Object
Set obj = CreateObject("NETProject.Foo")
obj.Move
Pretty easy. Except that you're late binding because you don't have a COM type library.
No problem! REGASM can generate a type library for you and even register it:
REGASM MyAssembly.dll /tlb:MyAssembly.tlb
Now, in VB6 you can add a reference to the type library and use early binding:
Dim net As Foo
Set obj = New NETProject.Foo
obj.Move
EDIT: Make the class COM visible like this:
[ComVisible(true)]
public ref class MyDataBaseAccessor
这篇关于如何在不通过 COM 的情况下从 VB6 调用 C++ DLL?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!