I have an old c dll that I want to convert to a COM server.
It only exposes one function.
This is what I have done:
I created an ATL project in VS 2010 added a simple ATL object with a wrapper function.
I added the c sources and headers
In the wrapper function I call the c function, I added the full function prototype as described in http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html#faq-32.5.
The following error appears:
Unresolved external symbol referenced in function
I tried everything.
Any idea?
You need to use extern "C" when including the c-source:
extern "C" {
#include "header.h"
}
You might try compile the c dll to a regular win32 dll, then calling it from you COM dll through a wrapper. You would need 2 dlls, but if the original DLL will compile fine, you should be able to use it from COM.
Related
I have a library of DSP functions in C++ and I want to link to them dynamically at run time. I am using the PDLL.h method to wrap my classes (for example FFT) into C-style functions and load them load on the fly in other C++ applications. I want to use these functions in .NET applications and COM components, so I have to use __stdcall which decorates the names in 32 bit builds.
In order to undecorate the names, I am using the trick mentioned here: C++ DLL Export: Decorated/Mangled names (wqw's answer, 2nd down). So for example, in my library's .h file I have declared my wrapped functions so:
#pragma comment(linker, "/EXPORT:DoFFT=_DoFFT#12")
RTLIBS_API DoFFT(FFT* x, DOUBLE* pdDataIn, DOUBLE* pdDataOut);
This does indeed work, and when I look into the dll with dependency walker, I see that there is both an entry for DoFFT and _DoFFT#12.
The problem that I have is that when I try to build a project that links to this library (dynamically, at run time, not using the .lib file at all) I get linker errors for all the functions in my dll, i.e.:
Error 31 error LNK2001: unresolved external symbol _DoFFT#12
I don't understand why this is happening. First of all, the symbol _DoFFT#12 does exist (according to dependency walker) and second of all, why is the linker looking for it in the first place? I am linking to it at run time, not at compile time so how does my project even know about this symbol?
All the functions are declared with the same chain of macros that reduces to (e.g.):
extern "C" __declspec(dllexport) int __stdcall DoFFT(FFT* x){...}
Nothing having to do with the library is declared on the client side.
I have created one static "C" library using VS.
I am using the same library file for another VS console C application its working fine but when I am working with windows forms app it's not working.
Referred so many queries in this forum but didn't get the Help.
Is there any naming conventions to call the static library functions from the Windows forms Managed c++ ?
Getting Errors Like this
error LNK2028: unresolved token (0A000032) "enum STATUS __clrcall
xyz(unsigned char)" (?xyz##$$FYM?AW4STATUS##E#Z) referenced in
function
__catch$?button3_Click#Form1#Myapp##$$FA$AAMXP$AAVObject#System##P$AAVEventArgs#4##Z$0
But I should use the same static library for both console and windows application.
The linker error message gives a strong hint what it going wrong. Note the __clrcall calling convention for the undefined symbol, it tells you that the compiler thinks that these are "CLR" functions. Managed code, of course they are not, they are __cdecl. There's more, the names are also mangled. Note the "##$$FYM?AW4STATUS##E#Z" curses in the name. Which tells you that the compiler thinks they were written in C++ instead of C.
You'll have to explicitly tell the compiler about this, the .h file isn't compatible enough. Which you do like this in your C++/CLI source code file:
#pragma managed(push, off)
extern "C" {
#include "yadayada.h"
}
#pragma managed(pop)
The #pragmas temporarily turn off managed code compilation mode so the compiler will now assume these are unmanaged function declarations. The extern "C" {} wrap around the #include tells the compiler that the .h file contains C declarations.
After googling, i came to know that Dllimport makes the function available for other modules,
is it mandatory to declare function with extern "c" identifier?
Also, Dllexport means, Dll itself uses the function while compiling it says. so by default all
functions present in DLL are dllexport?
__declspec(dllexport) exports a symbol. It makes it available from outside a DLL.
__declspec(dllimport) imports a symbol. It practically says "this symbol is not defined in this application, it needs to be imported from a DLL file".
You don't have to declare it with extern "C". If you don't use extern "C", then the symbol will be exported as a C++ symbol, and you will only be able to call it from C++ (and languages that support calling C++ DLLs). If you use extern "C", then the symbol will be exported as a C symbol, and you will be able to call it from languages that support caling C DLLs.
If you want to use your DLL in C#, you will need to use extern "C".
Here is an excellent tutorial that shows you how to use a C++ DLL in C#: How to marshal a C++ class. I have used solution A in many projects at work.
Also, here is a short tutorial on how you can use a C++ DLL in another C++ application: How to create and use DLL in C++.
No -- dllexport means you're exporting it from the DLL (or from an executable) so that other modules (DLLs or executables) can use that function.
dllimport is used to declare a function that's implemented in a DLL (or, again, executable).
So, in a typical case, you'll have something like:
#ifdef BUILDDLL
#define DLL declspec(dllexport)
#else
#define DLL declspec(dllimport)
#endif
Then each public function the DLL will be marked as DLL:
DLL int dosomething(int);
Then, when you're building the DLL, you'll define BUILDDLL, to have all those functions marked as dllexport. Otherwise, you'll include the same header in client code that needs to use the function(s). It won't define BUILDDLL, so they'll all be marked as dllimport instead, so when it comes to link time, it'll create a link to that DLL instead of trying to satisfy those functions from someplace like the standard library.
It also means that entries (in the form of static import and export tables) are created (by the linker) in the exe, dll..files, which document the dependencies between a provider and a consumer.
I've got to support an old app written in C using the old Borland Compiler (BC 5).
Unfortunately the old TCP/IP library that we'd used is starting to show it's age and is having problems with Vista & Win7 machines.
I have a new library of functions available for MS Visual C++, and I'd like to use that to make a DLL that would be callable from the Borland C.
So, I have 2 issues:
1) how to make a Visual C++ DLL callable from a Borland C program, and
2) if it is callable, how to call the C++ functions from plain old C?
Ideally, the entire project should be converted to Visual C, but there a lot of legacy features that'll make that project a major undertaking! I'm looking for a quick patch to keep it alive for a while longer :)
Steve
Write a DLL using Visual C++ that exposes its interface as Windows STDCALL C functions. Windows API functions are done similarly. Those functions you expose in the interface will perform the functions you need to replace in your program. Inside the DLL, call the new MS VC++ library with abandon.
So to get a function that is callable from C and uses STDCALL stack protocol do something like this:
extern "C" int __stdcall foo();
you'll also have to add information to export the function from the DLL. You might do this explicitly in the declaration as such:
extern "C" __declspec(dllexport) int __stdcall foo();
But you'll need a separate header file for use in your BorlandC code (which probably has different syntax for specifying the DLL import part and the STDCALL part). In Visual C++ the declaration you'd use in the client would look something like:
extern "C" __declspec(dllimport) int __stdcall foo();
You can create Borland OMF import libaries with Borland's IMPLIB utility: IMPLIB -a "whatever.omf" "whatever.dll", where the DLL file is that created by MSVC.
The -a option is for Microsoft compatibility. The generated OMF (Borland's import library file format), combined with a header file that specifies the exported functions and their calling convention(s) should work... (I believe IMPLIB was around in C++ Builder 5.)
http://docs.embarcadero.com/products/rad_studio/radstudio2007/RS2007_helpupdates/HUpdate4/EN/html/devwin32/implib_xml.html
I need in a DLL to use a class, defined in an executable (DLL and executable are compiled by the same compiler). But I don't want the source code of this class definition to be available to DLL, only declaration.
One possible way to do it is to make all the necessary class methods to be virtual (so that DLL linker will not need these methods' definitions). The disadvantages of this approach:
I cannot create objects of exported classes
in DLL code using new (a have to
create additional functions in
executable's code).
I have to make all these methods virtual,
even if otherwise they don't need to
be virtual.
There is a way to export a class from a DLL to an executable using Microsoft's __declspec(dllexport) storage-class extended attribute.
Is there a way to export a class from executable to DLL using the same technique?
My old Borland C 6 compiler does not allow me to create import library during the build of executable project. (So, when compiling the DLL, linker gives me unresolved external error messages for all imported non-virtual class methods.) Is it a limitation of this very compiler, or maybe I'm missing something important?
So far as I know, it is ok to use MS VS's dllexport to export a class or function from a exe and use it in a DLL. and it runs cool if your DLL and Exe execute in one process.
You could put the class in a second DLL if you really didn't want it in the first one.
I'm having a hard time understanding your reasoning for not just putting the class in the DLL though.
ETA: Did some more digging and found this link that explains how to generate an import library from an EXE project in Visual Studio 2008. As for how to export them, it looks like you just use the regular __declspec(dllexport).
OK, new answer in light of new information here. If you can't generate an export library for your EXE with your compiler, and you really really have to do it this way, here's a creative, hacky and generally not recommended solution:
Step 1: Create a C wrapper API for your class, kinda like this (probably wont compile, but you get the idea):
// Yes, need some 32 bit/64 bit checks here
#define MYHANDLE unsigned int
__declspec(dllexport) MYHANDLE MyClassNewInstance() {
MyClass* ptr = new MyClass();
return (MYHANDLE)ptr;
}
__delspec(dllexport) MyClassDoSomething( MYHANDLE handle, int parm ) {
MyClass* ptr = (MyClass*)handle;
ptr->DoSomething(parm);
}
etc..
Step 2: To actually get the C functions from the EXE for use in the DLL, use the Win32 API functions GetModuleHandle() and GetProcAddress().
Step 3: Create a proxy class in your DLL. The methods in the proxy class do nothing but call their counterpart C functions from the EXE.
This would keep the "real" implementation of your class out of the DLL. It's a hack, but it would probably work.