Work around for using C++ class with extern "C" DLL, class, function overloading, templates

Hello,
I've been betting my head against the wall trying to figure out how to be able to use all the tools of C++ while having to extern "C" the code to a DLL.

I understand name mangling is the issue, which brought me to the thought of having a host, and client DLL to be able to accomplish the task. I also tried to have two programs, a Server and a client, where the client would send the data to the Server program by TCP socket to do the C++ calculations and send the returned value back to the client. However, I found sending data between two programs by a TCP socket to be to slow.

So before I make the venture to create a host and client DLL to work around the extern "C" while using the tools of C++. I would like to hear your input, or maybe there is a different path to take.

However, I feel is it fees-able to use all the tools of C++ while having to extern the code to "C" by having a host and client DLL.
Example is as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// FILE: hostDll.dll .....................................................................................
// The Host DLL to be able to use the C++ tools
__declspec(dllexport) double CPPFunction(){
	// Be able to use function overloading, templates, ect.
}
// ........................................................................................................

// FILE: clientDll.dll ------------------------------------------------------------------------------
// Bring in the Host DLL to be able to use the C++ func while 'extern"C"'
extern "C" __declspec(dllimport) double CPPFunction(){
}

// the Client DLL the sends data to the Host C++ DLL
extern "C" __declspec(dllexport) double function(){

	// Sends the data to the Host DLL, the Host DLL is able to use C++ calc and returns the value
	// This way you get the best of both worlds, so you don't have to accomidate with having to use 'extern"C"'
	return CPPFunction();
}
// ------------------------------------------------------------------------------------------------------ 


Last edited on
I understand name mangling is the issue, ...
I don't quite understand what the problem is.

You can export C++ mangled names from DLLs, the C++ runtime does that, and pretty much everyone else.

Perhaps if you explained the problem, we may be able to provide a helpful answer.
Last edited on
The problem:
is with extern"C". If I have a class written in C++, try to incorporate it in a DLL, and have to use extern"C" woun't the program using this DLL have the potential to get confused because of name mangling.

So with extern"C" you can NOT overload functions, use templates, ect. from C++, right? So that is why I proposed a work around (the code above). So you could use the C++ tools (templates, func overloading) but be able to extern"C" because I'm using a Host DLL, that uses the C++ tools, imputed into a client DLL that has to use extern"C".

Would my work around work?

Also, does that make sense?
Last edited on
No workaround needed. You can export a class from a Dll and it'll be just the same as having it in the host. I do that occasionally with my String Class, that is, have the implementation in a dll, and have use of it in a host linked against the dll. I can provide examples if you like.
Only gotcha, is it isn't portable between compilers, because there is nothing that I know of in the C++ Standards that specify what the binary layout of a C++ class looks like. That's why COM was invented. So if you create the Dll with GCC, for example, it likely won't work with MSVC.
Thank you freddie1 for your answer, right it is not portable with compilers

That's why COM was invented. So if you create the Dll with GCC, for example, it likely won't work with MSVC.
Isn't that why you use extern"C"?

So if I bring a host DLL into the client DLL, and the client DLL is the only one with extern"C." Would the program using the client DLL mangle the names in the hostDll (inputed into the clientDLL) anyway, and my work around would not work, or would it work?
Last edited on
Doesn't extern "C" remove name mangling? I thought the whole point of extern "C" was to make code compatible with other languages and compilers.
Doesn't extern "C" remove name mangling?
Yes it does, but there's more a DLL than name mangling.

A DLL can export data, functions and classes. We folk always think exporting data is a bad idea.

Functions can be exported by name or by ordinal. It takes longer to search for a function name, than to look up a number. So back in WIN16, functions were looked up by name because the hardware was so slow.

It was with great relieve that C++ mangled symbols can be exported as easily as C symbols. And as long as you're interfacing with C++ systems built from the same mangling scheme, things are ok (heaps aside).

It turns out that classes can be exported too. If you look at the runtime libraries for MFC, you'll seem lots of exported classes and their members.

Finally, it's possible for your DLL to export interfaces with a C factory function. A C++ client can obtain an interface from the factory and make no further deman on the DLL interface mechanism.

So what makes this all so vendor specific?

1. Each vendor typically has their own name mangling scheme.
2. Each vendor typically has their own vtable scheme?
3. Heap arrangements.

Obviously, if a client cannot understand the naming convention of the code in the DLL, they're incompatible.

If the client and DLL have different vtable implementations, then they cannot use Object Oriented features; they can use STL but not streams for example.

Finally, what does int* a = int(f(x)); and delete [] a; mean when placed in a header file? One has to be careful. Do the new and delete refer to the same heap? They'd better. The implementation can go some way to help, but it's not always obvious what's right.

The operation system's native language is C. So what if you want to use C++ in a system wide way? The answer is COM. With reference to the 3 issues listed above:

It turns out that classes are identified by GUIDs, large unique numbers. Methods are offsets within each class. There's no generalization, only composition.

Almost coincidentally, the method ordering scheme with a class in COM, matches exactly the vtable scheme in Microsoft's compiler. Amazing!

Early COM interfaces supported different heaps (IMalloc), but that idea was dropped for the greater good.

I think that about covers it.
Thank you kbw for your various answers to my question.
-Andrew
Registered users can post here. Sign in or register to post.