问题
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)];
回答1:
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
回答2:
I'm not entirely sure what they are.
You are not looking at C++ code, but at C++/CLI code, a language targeting the managed .NET platform. This is also why you can easily use this DLL in C#.
Honestly, if you want to use managed objects in Visual Basic 6, COM Interop is your best bet. Either create a wrapper or directly expose the objects contained in the DLL via COM Interop.
Edit:
Basically, you expose objects by using attributes, i.e. you annotate your types in source code with attributes. Those are documented here: System.Runtime.InteropServices
Have a look at: Introduction to COM Interop
Also, the COM Interop "bible" is this book by Adam Nathan: .NET and COM: The Complete Interoperability Guide
There is also an article dealing with how to expose a COM object and use it in VB6: http://www.15seconds.com/issue/040721.htm
来源:https://stackoverflow.com/questions/3843350/how-to-call-a-c-dll-from-vb6-without-going-through-com