|
I have an unmanaged project that I will to compile in Managed C++. Is it just a matter of adding the /clr switch to the compiler options in VS2005/Project/Properties/C++/Command Line?
Thanks
alias47
|
|
|
|
|
Yes, that is, in theory, correct. However, I'm not sure if that will actually expose anything to the CLR ( if it's a dll ), it will simply make the .NET framework available to your application.
Christian Graus - Microsoft MVP - C++
Metal Musings - Rex and my new metal blog
|
|
|
|
|
So, is the solution to create Managed C++ wrapper for each exported routine?
|
|
|
|
|
alias47 wrote: So, is the solution to create Managed C++ wrapper for each exported routine?
What exactly is your scenario? That might help people give a more suitable answer.
|
|
|
|
|
If you want to export C++ methods to be exposed to .NET, then probably, but as Nish said, some more info would help.
Christian Graus - Microsoft MVP - C++
Metal Musings - Rex and my new metal blog
|
|
|
|
|
Thanks for your help guys. I have a c++ MFC DLL, written in Visual c++ 6.0. This DLL is currently called from an Excel VBA application and has some callbacks back to Excel in it. I have rewritten all of the VBA code into a non-VSTO shared managed add-in in c#, written in VS2005. I want the managed addin to call the c++ DLL the same way VBA used to. In its current form if I add a reference in the managed addin to the c++ DLL, a message says that it is not a valid assembly or COM component. If I compile the c++ DLL in VS2005 without the /clr switch it makes no difference, except that the Excel VBA application does not work anymore. If I try to use a DLLImport with the c++ DLL, I receive a "memory may be corrupt" message. The c++ DLL exports about 30 functions, as specified in a DEF file. Do I need a Managed c++ wrapper around these functions to access them from C#. Is there some boilerplate code to use? Does it depend on what the functions are?
Sample of the first function exported:
extern "C"<br />
short int DLLFUNC FunctionX()
DLLFUNC defined:
#ifndef DLLFUNC<br />
#ifdef WIN32<br />
#define DLLFUNC _stdcall<br />
#else<br />
#define DLLFUNC WINAPI _export // DLL functions are FAR PASCAL _export<br />
#endif<br />
#endif
Regards
alias47
|
|
|
|
|
Hello,
alias47 wrote: Do I need a Managed c++ wrapper around these functions to access them from C#?
Yes.
alias47 wrote: Is there some boilerplate code to use?
Check out this CP article: Using Microsoft Interoperability Libraries.
alias47 wrote: Does it depend on what the functions are?
No.
Best,
Jun
|
|
|
|
|
I *really* need someone to help me out.. I am wasting heaps of time trying to access this unmanaged c++ DLL from C#. It is a showstopper.
Let me check my understanding on a few issues:
IJW: Does IJW mean "Just compile unmanaged c++ code in VS2005" and then reference the unmanaged DLL in C#. If so, this does not work.
COM: How can I tell that the unmanaged c++ DLL is not COM-based? (Apart fromn the message I receive when trying to reference the DLL from C#)
PInvoke: When using this from C# to the c++ DLL, I receive a message about corrupt memory. Is this because the type of the argument is incorrect? In c++ the type is IDispatch. In C# I am passing an object type. In fact it is an Excel.Application type which is being cast to object that I am passing. Will this PInvoke technique possibly work if I pass a different type?
The article http://www.codeproject.com/useritems/usingcppdll.asp seems comprehensive, but I wonder whether I need to do any/all of this.
The unmanaged c++ DLL works prefectly currently with Excel. I guess that is because excel is itself unmanaged? Is the approach found http://groups.google.com/group/microsoft.public.dotnet.languages.vc/browse_thread/thread/8c538b0e1bbf020b/cac8b5f6bb7932ef%23cac8b5f6bb7932ef
too simplistic?
Surely there is an app in vs2005 that autogenerates the managed wrapper? Surely? Like http://www.codeproject.com/dotnet/NativeWrapper.asp
Regards
alias47
|
|
|
|
|
alias47 wrote: IJW: Does IJW mean "Just compile unmanaged c++ code in VS2005" and then reference the unmanaged DLL in C#.
The first half is correct. IJW only compiles unmanaged code and leave it in the unmanaged context. It won't make it callable by managed code, meaning you can't add unmanaged DLLs as references to managed projects.
alias47 wrote: COM: How can I tell that the unmanaged c++ DLL is not COM-based? (Apart fromn the message I receive when trying to reference the DLL from C#)
Your header and source files should indicate COM interfaces and their implementations. If your modules has implemented IDispatch, then the module is a COM-based. Check this site for how to PInvoke COM in managed C++.
alias47 wrote: PInvoke: When using this from C# to the c++ DLL, I receive a message about corrupt memory. Is this because the type of the argument is incorrect? In c++ the type is IDispatch. In C# I am passing an object type. In fact it is an Excel.Application type which is being cast to object that I am passing. Will this PInvoke technique possibly work if I pass a different type?
Probably because the first two issues have not been resolved properly.
Best,
Jun
|
|
|
|
|
Jun Du wrote: Your header and source files should indicate COM interfaces and their implementations. If your modules has implemented IDispatch, then the module is a COM-based. Check this site for how to PInvoke COM in managed C++.
Hey Jun,
he just has an MFC DLL with some exported functions. I don't think it's a COM DLL. So all he seems to need is a bunch of DllImport definitions.
|
|
|
|
|
That is what I first thought too. Actually on his another discussion thread on the same topic, he said it's not a COM module. But somewhere in this thread, he indeed mentioned IDispatch interface. I guess he needs to know what he is asking first.
Best,
Jun
|
|
|
|
|
Jun Du wrote: I guess he needs to know what he is asking first.
Yes, he does.
|
|
|
|
|
alias47 wrote: In its current form if I add a reference in the managed addin to the c++ DLL, a message says that it is not a valid assembly or COM component.
You don't need to add a reference. You can call imported functions from C# using the DllImport mechanism. That's all you'd need for your scenario.
|
|
|
|
|
|
alias47 wrote: anyone?
Looks like the people answering questions are not in your time zone
|
|
|
|
|
This is a total newbie question. I have a MSDN subsciption and have installed VS 2005. Where do I go to install Managed Extensions for C++.
Regards
alias47
|
|
|
|
|
File/New/Project/C++/CLR
It's already there.
Christian Graus - Microsoft MVP - C++
Metal Musings - Rex and my new metal blog
|
|
|
|
|
Thank you for your help. CLR does not seem like an obvious name for Managed c++ though. Oh well.
|
|
|
|
|
It's called C++/CLR now, it has a new name because of the changes in 2.0. CLR stands for Common Language Runtime.
Christian Graus - Microsoft MVP - C++
Metal Musings - Rex and my new metal blog
|
|
|
|
|
Christian Graus wrote: It's called C++/CLR now, it has a new name because of the changes in 2.0. CLR stands for Common Language Runtime.
C++/CLI actually - Common Language Infrastructure
|
|
|
|
|
*sigh* I don't know where that stupid mistake came from.
Christian Graus - Microsoft MVP - C++
Metal Musings - Rex and my new metal blog
|
|
|
|
|
Christian Graus wrote: I don't know where that stupid mistake came from.
STL.NET was renamed to STL/CLR - maybe that stuck on your mind.
|
|
|
|
|
I set up a DLL to define a class library. At first I set up the DLL as a native Win32 build. The calling app, however, was a C++/CLI app. The code below works fine:
<br />
#ifdef EXPORTING <br />
#define MYAPI __declspec(dllexport) <br />
#else <br />
#define MYAPI __declspec(dllimport) <br />
#endif <br />
<br />
class MYAPI MyClass() <br />
{ <br />
public: <br />
MyClass(); <br />
int DoSomething(); <br />
} <br />
<br />
<br />
#include "MyDll.h" <br />
... <br />
MyClass *x = new MyClass(); <br />
System::Console::WriteLine(System::String::Format("You got {0}", x->DoSomething()); <br />
delete x; <br />
...<br />
Building the main app with a project reference to the MyDll.dll, everything is FINE. Works great!
Now, after a little while I decided that my native class wants to have invoke some managed code (like file I/O). To do this, of course, I now have to build the DLL with the /clr option. This, in turn, totally breaks my class calling code in the main app. Mind you, I have not even added any managed code to the class yet. Just adding the /clr option and rebuilding the project killed everything.
To be specific, I get linker error messages for every public class symbol in the class, saying that the symbol is not defined. Remember, the main app project was already set to reference the dll. But for the fun of it I tried removing the project reference and manually adding #using <mydll.dll>. This did not help.
What do I need to do to get rid of the linker errors? Why is everything fine when I build the DLL as a Win32 dll?
Thanks for your help.
|
|
|
|
|
Could you copy/paste the linker errors here?
|
|
|
|
|
I made my original post without the code in front of me, so I had the wrong class name. In the error messages below, CClass32 is the native class in the DLL I am calling (a.k.a. "MyClass" in the original post). The errors were generated building the calling app with a project refernce to the DLL built with the /clr switch. When the DLL is built with no CLR support, the calling app builds with no errors or warnings.
Also, sorry for the misinformation. I forgot I got out of console mode and tried plugging this into a windows form. In the form class, I declared a private variable "pc" as a pointer to CClass32. I put a call to pc->DoSomething() in the destructor because the whole project is just a learning test (so I was too lazy to set up a button click event in the form). That's why these error messages look like they do. I don't actually expect to execute the app. But I do need to understand this whole process and need this test to build before I embark on porting one of my very large c++ 6.0 projects into a semi-managed .NET application.
Having said that, here are the errors:
Error 1 error LNK2028: unresolved token (0A000017) "public: int __thiscall CClass32::DoSomething(void)" (?DoSomething@CClass32@@$$FQAEHXZ) referenced in function "private: __clrcall CLIGLTest2::Form1::~Form1(void)" (??1Form1@CLIGLTest2@@$$FA$AAM@XZ) CLIGLTest2.obj
Error 2 error LNK2019: unresolved external symbol "public: int __thiscall CClass32::DoSomething(void)" (?DoSomething@CClass32@@$$FQAEHXZ) referenced in function "private: __clrcall CLIGLTest2::Form1::~Form1(void)" (??1Form1@CLIGLTest2@@$$FA$AAM@XZ) CLIGLTest2.obj
Error 3 fatal error LNK1120: 2 unresolved externals C:\Files\VsNet 2005\CLIGLTest2\Debug\CLIGLTest2.exe 1
When I add in the form constructor the code pc = new CClass32(); the errors are doubled, producing similar messages saying that the symbol "public: __thiscall CClass32::CClass32(void)" is not defined. So it's like the DLL doesn't even exist as far as the calling app is concerned. But as I said, I used the IDE to point to the DLL where CClass32 is defined, so I know it's not a malformed #using directive or something.
-- modified at 22:38 Thursday 17th August, 2006
|
|
|
|