.NET Forum / Languages / Managed C++ / November 2006
Compiling C DLLs for reuse in MC++?
|
|
Thread rating:  |
WebSnozz - 22 Nov 2006 19:04 GMT I have an application written in C that does a lot of low level stuff. It does a lot of things like casting from void*'s. I want to create a new GUI for it in either C# or MC++, but reuse the existing code.
The options I've considered so far:
1. Create a new MC++ GUI project and add the *.c files to them and mark them with pragma unamanged. However, the /clr option does not compile *.c files, so I rename them to *.cpp, and now they will not compile due to c operations not legal in cpp. Most of the compilation errors are related to perform casts such as: (classname*)somethingDeclaredAsVoidPointer;//compile error indicates unable to perform cast from void* to classname*.
I think there is a specific syntax I can use to make these casts compile successfully(I understand these types of casts are not type safe), but my goal is to modify the code as little as possible, and there a very large number of errors in the C code when I try compiling as cpp. It's not a big task to change them, but I wanted to try and use the same c files for compiling the old version of the app also, which would probably involve some #ifdef statements to allow inclusions/exclusion of code depending on what project it's being compiled from.
2. Compile the C code as a DLL. Make calls to the DLL from MC++ or C# whenever a function is needed. I am not quite sure how to do this. I took the C project, and changed the output type from Application to DLL and with a few tweaks, got it to compile successfully. However, if I set the DLL project as a dependency of my C++ project, then it gives me errors stating the I cannot link with a native DLL because the clr option is enabled(referring to the clr option in the MC++ project).
So I have no idea how to use the native DLL from MC++. The only example I found was actually compiling the C code as *.cpp files with the /clr:oldsyntax option. This option is not compatible with *.c files, and changing them to *.cpp files puts me back where I was with option #1.
This is the part where I lack understanding of native C/C++ DLL's. I've never made a native DLL before and successfully used it. I have no problems in .NET, but of course things seem to be alot simpler in .NET, as public class are automatically exposed, and register the DLL, and then other applications just referrence the DLL via it's namespace.
How does my MC++ application get knowledge of and make function calls into functions in the native C DLL?
3. Have the C program continue to run as it's own application, but not show it's GUI, and instead, post message or communicate with the C# or MC++ application. I don't know if I can do this with some kind of posting of messages, or communicating over sockets. I have some conceptual ideas, but the ideas are way beyond me.
4. Compile the MC++ as a native DLL, and have the C application make calls into the DLL to spawn the GUI and communicate over function calls which make requests of the GUI thread. I am pretty confident with threading in either context. The part that I am wary of, is again how to make DLL calls. I haven't tried this, but I imagine I will have the same problem as #2. I don't have a lot of experience with native DLLs, and if I try to implement this just as it would have been in old school C/C++, then I'm afraid my efforts will not be fuitful when I found out that for some reason, once again the /clr option tells me I can't link to a MC++ DLL from a C application. If there's something special I need to do, I need to know that.
I think option #2 or #4 are probably my most preferred options, but I am having trouble figuring out how to give one application "knowledge" of the other DLL. I'm used to scenarios in C# where I just add a reference, and walla, I can use the namespace, or in C++ where I just set a dependency to the DLL and VS seems to magically take care of linking them together. I am spoiled by VC++. The only time I haven't used it either when using languages not supported by VS, or when writing under linux, but have never made a DLL in either of those contexts.
Any suggestions are appreciated, or pointing me to good examples of these scenarios that are using truly native C(not cpp files compile with /clr:oldsyntax).
Bruno van Dooren [MVP VC++] - 22 Nov 2006 19:47 GMT > I have an application written in C that does a lot of low level stuff. > It does a lot of things like casting from void*'s. I want to create a > new GUI for it in either C# or MC++, but reuse the existing code. > > The options I've considered so far:
> 2. Compile the C code as a DLL. Make calls to the DLL from MC++ or C# > whenever a function is needed. I am not quite sure how to do this. I [quoted text clipped - 3 lines] > errors stating the I cannot link with a native DLL because the clr > option is enabled(referring to the clr option in the MC++ project). This is what I would do if your code is pure C code. It has the advantage that you don't have to change anything to existing code. Could you paste the exact error message?
> This is the part where I lack understanding of native C/C++ DLL's. > I've never made a native DLL before and successfully used it. I have [quoted text clipped - 4 lines] > How does my MC++ application get knowledge of and make function calls > into functions in the native C DLL? Just include the include file, and link with the lib file.
> 3. Have the C program continue to run as it's own application, but not > show it's GUI, and instead, post message or communicate with the C# or > MC++ application. I don't know if I can do this with some kind of > posting of messages, or communicating over sockets. I have some > conceptual ideas, but the ideas are way beyond me. lots of overhead. you don't want to do this.
> 4. Compile the MC++ as a native DLL, and have the C application make > calls into the DLL to spawn the GUI and communicate over function calls [quoted text clipped - 7 lines] > to a MC++ DLL from a C application. If there's something special I > need to do, I need to know that. I would not do this either. you would have to change you existing code, and it would take more designing and testing.
www.codeproject.com is always a good place to start.
 Signature Kind regards, Bruno van Dooren bruno_nos_pam_van_dooren@hotmail.com Remove only "_nos_pam"
WebSnozz - 22 Nov 2006 20:13 GMT Thank you for your response.
"Just include the include file, and link with the lib file"
Just to clarify some things: So in the MC++ program I would just add the c lib file as an item in the project, or specify in the project Linker properties the location of the lib as additional libraries to link?
Should VS be generating a lib file automatically just by me making the output type DLL? If the answer is no, then I will try to research this myself. If the answer is yes, then I am confused because there is only a DLL file, no lib. (Maybe because I haven't started defining functions as extern or added the DLLMain or whatever the main is for a DLL.)
The header file you refer to will be the one where I declare function signatures as extern? I am not knowledgeable of those things yet, but I'm sure I can find lots of documentation on making native C DLLs. I just want to verify that you are referring to the .h files made especially for the native C DLL, and not referring to the *.h files that were a part of the original C executable application for it's own use?
Thanks again.
> > I have an application written in C that does a lot of low level stuff. > > It does a lot of things like casting from void*'s. I want to create a [quoted text clipped - 56 lines] > bruno_nos_pam_van_dooren@hotmail.com > Remove only "_nos_pam" Bruno van Dooren [MVP VC++] - 23 Nov 2006 07:25 GMT > "Just include the include file, and link with the lib file" > > Just to clarify some things: > So in the MC++ program I would just add the c lib file as an item in > the project, or specify in the project Linker properties the location > of the lib as additional libraries to link? If you do it manually, you have to specify it in the linker input tab. You can also make it a dependency, in which case it happens automatically.
> Should VS be generating a lib file automatically just by me making the > output type DLL? If the answer is no, then I will try to research this > myself. If the answer is yes, then I am confused because there is only > a DLL file, no lib. (Maybe because I haven't started defining > functions as extern or added the DLLMain or whatever the main is for a > DLL.) Yes, it should do this, but it only does this if there are exported functions. if there are no exports, it will not create a lib file.
> The header file you refer to will be the one where I declare function > signatures as extern? yes, those header files. but extern is not enough. you have to use either __declspec(dllexport) or add a DEF file to your project.
>I am not knowledgeable of those things yet, but > I'm sure I can find lots of documentation on making native C DLLs. I > just want to verify that you are referring to the .h files made > especially for the native C DLL, and not referring to the *.h files > that were a part of the original C executable application for it's own > use? No, I mean the header file that has the declaration for the exported functions.
 Signature Kind regards, Bruno. bruno_nos_pam_van_dooren@hotmail.com Remove only "_nos_pam"
Ben Voigt - 24 Nov 2006 15:11 GMT >> "Just include the include file, and link with the lib file" >> [quoted text clipped - 23 lines] > you have to use either __declspec(dllexport) or add a DEF file to your > project. for a .lib, you just need extern. For a .dll you need also declspec(dllexport) when building the dll, and declspec(dllimport) in clients.
>>I am not knowledgeable of those things yet, but >> I'm sure I can find lots of documentation on making native C DLLs. I [quoted text clipped - 5 lines] > No, I mean the header file that has the declaration for the exported > functions. Ben Voigt - 22 Nov 2006 20:10 GMT > I have an application written in C that does a lot of low level stuff. > It does a lot of things like casting from void*'s. I want to create a > new GUI for it in either C# or MC++, but reuse the existing code. Since you mention /clr:oldSyntax, you must have VC++ 2005, which is C++/CLI, not Managed C++. I hate to be picky about this, but the two are utterly incompatible. Even with /clr:oldSyntax, VC++ 2005 doesn't follow the rules for MC++.
> The options I've considered so far: > [quoted text clipped - 5 lines] > (classname*)somethingDeclaredAsVoidPointer;//compile error indicates > unable to perform cast from void* to classname*. There are very few things in C that the C++ compiler rejects... the only thing I ever have to do is add any missing prototypes.
Your statement is a little suspicious "(classname*)somethingDeclaredAsVoidPointer" because C doesn't have classes. I'm going to take a wild guess and say that the cast target type is a function pointer... you can't cast between data and function pointers in C++. Any other C-style cast would still be valid.
You can make this C++ compatible, while staying valid C, as follows:
typedef void (*functionptr_t)();
and use functionptr_t instead of void* when you need to cast function pointers.
> I think there is a specific syntax I can use to make these casts > compile successfully(I understand these types of casts are not type [quoted text clipped - 5 lines] > inclusions/exclusion of code depending on what project it's being > compiled from. You can do this as well. I have a third-party C library which I compile without /clr into a static library. I then have a managed C++/CLI assembly that links the native library (.lib) in with no problem. Note: you have to use /clr, not /clr:pure or /clr:safe, to interact with native code and data.
The only #if you would need is the well-known incantation for header files shared between C and C++: #if __cplusplus extern "C"{ #endif
...
#if __cplusplus } #endif
Don't use #ifdef, because I know of at least one major compiler than defines __cplusplus to 0 in .c files when compiling a mixture of C and C++.
If the C code was originally a standalone application, you may end up with a collision on "main". The right thing to do here is make a static library with all the reuseable pieces, not including main.
WebSnozz - 22 Nov 2006 20:46 GMT Thanks Ben,
I remember I was able to compile the c program as a static library, but I had trouble linking. Is going into the VC++ GUI project and setting a dependancy on the C lbirary project the correct way to link them? Or should I be going under the Linker section of the project properties and pointing it to where the library is at? I have also seen people just add the *.lib files into the project under solution explorer, but I am not sure if this automatically causes them to be linked?
I will try your suggestions when I get home, but if you could clarify the above for me, thanks.
Yes indeed, it is VS 2005. The only reason I mentioned /clr:oldsyntax was because the one example I saw used that for the C(but *.cpp files) DLL: http://www.etro.vub.ac.be/Personal/bjansen/dlls/interfacing.html#cdll
But this example didn't really work well for me because my project chokes on the /clr:oldsyntax option that they use, and without it I wasn't able link to the DLL. Anyhow, I am curious about what you mean in regards to VS2005 being "VC++ 2005, which is C++/CLI, not Managed C++". I will read up on this. Are you implying that I might find 2003 easier for this sort of thing?
You are right about the error not being class related. Those cases were actually casting to a struct or sometimes a typedef of some sort of primitive type like a char*. Whenever I see something that is not a standard type name, I immediately think of class when I really should think, "Type name defined by user which could be a typedef, class, struct, or who knows what else."
There are also a lot of function pointers also. I haven't gone through and read every error message to see if any are function pointer related. I will look at the exact error messages again when I get home, and perhaps I will be more persistent now that you've given me encouragement on these things.
> > I have an application written in C that does a lot of low level stuff. > > It does a lot of things like casting from void*'s. I want to create a [quoted text clipped - 64 lines] > collision on "main". The right thing to do here is make a static library > with all the reuseable pieces, not including main. Ben Voigt - 22 Nov 2006 21:17 GMT > Thanks Ben, > [quoted text clipped - 5 lines] > just add the *.lib files into the project under solution explorer, but > I am not sure if this automatically causes them to be linked? I actually have two native static libs in my current workspace. One, I don't even have source for, just dropped the .lib into solution explorer and imported the vendor header file like this:
extern "C" {
#include "nameofthelibrary.h"
};
The other one I compiled from source, and in the C++/CLI project, I right-click the project in Solution Explorer, choose References, and added a project reference which automatically sets the build order dependency and pulls the .lib into the linker. The C++/CLI mantra is "It Just Works", and well, it does. For that one I had to match the vendor's structure packing because the buffers are passed intact to a driver binary:
#pragma pack(push, 1)
extern "C" {
#include "nameoftheotherlibrary.h"
}
#pragma pack(pop)
> I will try your suggestions when I get home, but if you could clarify > the above for me, thanks. [quoted text clipped - 10 lines] > C++". I will read up on this. Are you implying that I might find 2003 > easier for this sort of thing? No! VC++ 2002/2003's Managed C++ is evil incarnate.
> You are right about the error not being class related. Those cases > were actually casting to a struct or sometimes a typedef of some sort [quoted text clipped - 86 lines] >> collision on "main". The right thing to do here is make a static library >> with all the reuseable pieces, not including main. AaronLShumaker@gmail.com - 23 Nov 2006 01:41 GMT Thanks again Ben.
> > Thanks Ben, > > [quoted text clipped - 140 lines] > >> collision on "main". The right thing to do here is make a static library > >> with all the reuseable pieces, not including main.
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|