The Joel on Software Discussion Group (CLOSED)

A place to discuss Joel on Software. Now closed.

This community works best when people use their real names. Please register for a free account.

Other Groups:
Joel on Software
Business of Software
Design of Software (CLOSED)
.NET Questions (CLOSED)
TechInterview.org
CityDesk
FogBugz
Fog Creek Copilot


The Old Forum


Your hosts:
Albert D. Kallal
Li-Fan Chen
Stephen Jones

C Dll's from VB 6.0

Is it really as painful as I think it is?  Do I have to use the .def file to avoid decorating the names with a prepended underscore and an appended @number_bytes_in_parameters?  Are there any tools that will automagically generate the .bas file with the function declarations and data types?

I thought old-school VB would make this stuff super easy, and it *almost* is.
Ryan Phelps Send private email
Thursday, January 26, 2006
 
 
Another option would be to use ATL to wrap the C API in a COM object model that would be easily consumed by a VB6 client.
ATL/COM dude
Thursday, January 26, 2006
 
 
I agree with ATL/COM guy above. Even if you aren't familiar with ATL/COM, you will save yourself so many debugging headaches later by going this route, it's well-worth your time. (Plus knowing ATL/COM is a great bragging right, not to mention incredibly useful in almost every windows development project.)

A great book on the subject is "Developer's Workshop to COM and ATL 3.0" by Andrew Troelsen. Probably goes into more detail than you need, but FINALLY learning the intricacies of IUnknown is well worth it if you have the time.
matt Send private email
Thursday, January 26, 2006
 
 
It is fairly easy.  The .def file merely causes the listed routines to be added to the export header of the binary.  It doesn't stop name mangling.  To stop the name mangling, simply compile it as C code (routines.c vs routines.cpp) or use the extern "C" directive.

e.g.

extern "C" __declspec(dllexport) int foo(void);

__declspec(dllexport) int foo(void) {
 return 0;
}

__declspec(dllexport) does the same as a .def file.  The extern "C" stops the mangling.
cipher
Thursday, January 26, 2006
 
 
COM is not easy, especially if you didn't use it before.
midtown programmer Send private email
Thursday, January 26, 2006
 
 
You also need to declare __stdcall calling convention on the functions exported.
Burner
Thursday, January 26, 2006
 
 
cipher:

#ifdef JCAM_DLL_EXPORTS
  #define JCAM_DLL_API extern "C" __declspec(dllexport)
#else
  #define JCAM_DLL_API __declspec(dllimport)
#endif
#ifdef __cplusplus
  namespace myCompany {
  //Use C symbol naming conventions
  extern "C" {
#endif //__cplusplus

/*Function declarations...*/

#ifdef __cplusplus
  } //extern "C" {
  } //namespace myCompany {
#endif //__cplusplus

Despite the extern "C" {} block, and the extern "C" in the declaration of __declspec(dllexport), it still decorated the names in the .dll file.  The only way I could get it to work was to put the function names in the EXPORTS section of the .def file, although I didn't have to put anything else.
Ryan Phelps Send private email
Thursday, January 26, 2006
 
 
Burner:

I realized that yesterday.  I was astonished how light the documentation on making a C++ dll for VB users is.  It's like they don't want you to do it or something.  It's not hard once you know, but going from 0 to 60 on that topic hard to do alone.
Ryan Phelps Send private email
Thursday, January 26, 2006
 
 
Like others, I'd recommend creating "traditional" extern windows DLLs instead of COM based ones for the reasons others have stated. And if so, just remember to use fixed length VB strings when making those Win C DLL function calls.
Green Eggs and Ham Send private email
Thursday, January 26, 2006
 
 
Ryan:

I'm not sure why it didn't work for you, but I tested my code before posting.  The __declspec(dllexport) negates the need  for the .def file.

Good luck.
cipher
Thursday, January 26, 2006
 
 
You added "namespace" declartion before "extern C". I believe compiler will decorates the name after it sees that.
Burner
Thursday, January 26, 2006
 
 
I haven't used DEF files in years.

Here's how I do it.

//////////
//
// Dll.h
//
/////////

#ifndef __DLL_H
#define __DLL_H

#ifdef __cplusplus
extern "C" {
#endif

__declspec(dllimport) int __stdcall Foo1();

#ifdef __cplusplus
}
#endif

#endif


//////////
//
// Dll.cpp
//
/////////

#ifdef __cplusplus
extern "C" {
#endif

__declspec(dllexport) int __stdcall Foo1();

#ifdef __cplusplus
}
#endif

int  __stdcall Foo1()
{
  return(0);
}

///////////////////////////

With this method, the DLL user does not need to worry about #defines in the makefile to deal with __declspec(dllimport) vs. __declspec(dllexport).

The DLL .H file is always __declspec(dllimport).
MBJ Send private email
Friday, January 27, 2006
 
 
"I'm not sure why it didn't work for you, but I tested my code before posting.  The __declspec(dllexport) negates the need  for the .def file."

You need to wrap it in extern "C" if the file is being included into a .cpp file.  If it is a straight .c file you really dont need the extern "C".  You should have the extern "C" though this will allow proper linkage for .c or .cpp program.

Mike
MikeG
Friday, January 27, 2006
 
 
MikeG:

See my original post.
cipher
Friday, January 27, 2006
 
 
If you use ATL, for god's sake, do not fire a event into VB6 from any other thread but the main Windows pump thread.
This has wasted weeks and weeks of my teams time.
Yawn
Friday, January 27, 2006
 
 

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
 
Powered by FogBugz