views:

31

answers:

2

I have written a standard DLL in Visual Studio 6 C++. I have also written a typelib to go with it so that it can be used directly in VB6 rather than via Declare.

It works fine in VB6 under Windows XP.

What doesn't work is when I take the DLL and the TLB into Vista and Windows7. There the .TLB registers fine with REGTLIB but the only symbol that is visible in Visual Studio 2008 is the Attribution constant.

The technique I'm attempting to emulate is found at How To Make C DLL More Accessible to VB with a Type Library. Is it the case that this technique no longer applies???

The (abbreviated) ODL code is reproduced below. Any idea what's going on?

// This is the type library for BOBDE.dll
[
    // Use GUIDGEN.EXE to create the UUID that uniquely identifies
    // this library on the user's system. NOTE: This must be done!!
    uuid(EE090BD0-AB6C-454c-A3D7-44CA46B1289F),
    // This helpstring defines how the library will appear in the
    // References dialog of VB.
    helpstring("BOBDE TypeLib"),
    // Assume standard English locale.  
    lcid(0x0409),
    // Assign a version number to keep track of changes.
    version(1.0)
]
library BOBDE
{
    // Now define the module that will "declare" your C functions.
[helpstring("Functions in BOBDE.DLL"), version(1.0),dllname("BOBDE.dll")]   
    module BOBDEFunctions
    {
[helpstring("Blowfish Encode ASCII for ANSI"), entry("BEA_A")] 
    void __stdcall BEA_A( [in] BSTR p1, [in] BSTR p2, [out,retval] BSTR* res );
    // other very similar functions removed for the sake of brevity
const LPSTR Attribution = "This product includes cryptographic software written by Eric Young ([email protected])"; 
    } // End of Module
}; // End of Library
+2  A: 

The problem here is that you not just changed the operating system, you also changed your development tools. It should still work if you run VB6 on Win7. But Visual Studio 2008 supports VB.NET, a very different language from VB6. It only supports 'true' type libraries, the ones that COM uses.

Calling an exported function from a DLL requires using the P/Invoke marshaller built into .NET. Check out DllImportAttribute and the VB.NET Declare statement in the MSDN Library. The declaration for that function ought to resemble this:

<DllImport("bobde.dll")> _
Function BEA_A( _
      <MarshalAs(UnmanagedType.BStr)> ByVal p1 As String, _
      <MarshalAs(UnmanagedType.BStr)> ByVal p2 As String) _
    As <MarshalAs(UnmanagedType.BStr)> String
End Function

No need to register a type library with this. Writing a managed class wrapper in the C++/CLI language would be another approach.

Hans Passant
"It should still work if you run VB6 on Win7" is probably the real issue in my case. A work colleague has Win7. I have Server2008 and a few VirtualBox VMs with XP and Ubuntu therein.
boost
I really do like the code you've demonstrated there, though.
boost
It is really unclear to me what actual tools you are using. The declaration I posted will only work in VB.NET, not in VB6.
Hans Passant
+1 BTW the VB6 runtime is supported on Server2008 and Win7. If you are using VB.Net, you need P/Invoke header like Hans has posted. You can create this P/Invoke code automatically from the C++ headers using the [P/Invoke Assistant](http://clrinterop.codeplex.com/) from the Microsoft CLR Interop team
MarkJ
A: 

Any reason you are creating typelib and not just declaring functions in VB6? Putting

Private Declare Function BEA_A Lib "bobde.dll" _
(ByVal p1 As String, ByVal p2 As String) As String 

at the top of your module seems a lot simpler.

Kris Erickson
Simple answer: Intellisense. Added answer: Strings going to DLLs via Declare get converted to ANSI. I wanted to be able to pass BSTRs. The typelib approach makes that possible.
boost
It's a small pain, but if you want wchar* you can varptr() the string. To me, anything I can avoid registering and cluttering the registry and uninstaller with the better.
Kris Erickson
Actually, StrPtr is better for Strings than VarPtr ... well, at least in my experience FWIW.
boost