is there any way to make a wrapper clr:safe for a project in C++ unmanaged?
My little story started this way,
"Boy, you have to do a project 'C# COM Interop' but this one have to use a 'C++ library' and must result in only 'one' (dll COM)."
Ok, after a few days searching, I realized that is possible to use C++ library in two ways: adding in Resources and calling with PInvoke or creating a wrapper C++/CLI. With PInvoke I can not have only one dll(right?). So I opted for the second option "wrapper C++/CLI". Seemed easy at the beginning, I recompile the library Visual Studio 2005 to 2010, create a CLR project (with keypair.snk and re-signed) added the library. Works! \0/ Now I will use the ILMerge, ohhhoo what is this? Only clr:safe? Why? OK, I try to recompile C++/CLI to clr:safe but erros appears...
How can I fix this?
Thanks in advanced,
ILMerge isn't the right tool for this.
Instead, you compile the C# to a .netmodule, and pass that to the C++/CLI linker along with all the C++/CLI object files.
Related
I have to use a third-party dll in my C++ project. All I know about this dll is that it was built in Visual Studio 2013. I use VS2010 and can not switch to 2013 because reasons.
Said dll exports some functions that return std::string. Unsurprisingly, calling those functions produces an access violation in some string deallocation code.
As far as I understand the problem, that's nothing to be surprised of, also nothing that could be done about other than switching to VS2013, which I can't.
Here is the thing though. This third-party dll comes with a c# example project that imports it and works just fine!
So my questions are:
(purely theoretical one) Why? Is it .NET string marshaling magic at work?
Suppose I wrap the offending dll in a managed dll of my own, then use that managed wrapper in my unmanaged code. Will it work?
If the answer to question 2 is yes, then how? I know literally nothing about c# so i wouldn't mind a few pointers.
EDIT:
So out of pure desperation I tweaked the imported function signature in my project - it was std::string (__cdecl *TFunc)();, changed it to BSTR (__cdecl *TFunc)(); - and it works! even though both library manual and the dependency walker tool insist std::string is correct. Posting this as an edit and not an answer because I still don't know what's going on here and it is scary.
http://www.astro.com/swisseph/swephprg.htm
I am trying to add swedll32.dll as reference into visual studio 2010 through add Reference in my project.
But it's giving an error message:
reference can not be added, please make sure that the file is accesible,
and that is a valid assembly or com component
Can anybody help me in adding this dll to visual studio?
The dll is a native, unmanaged dll. The development started 1997, 4 years before .NET even became available. You will need to find a way to either PInvoke the methods or use a programming language better suited to interface with it like Cor C++.
You may want to start reading about DllImport, which is a way to import native dlls to call from managed code. This is a good starting point.
I've read many solutions to the issue of using C# code in a C++ project, including this one: How to use c# code in C++ project
I've also read this, and one answerer says Compile your C++ code with the /clr flag. With that, you can call into any .NET code with relative ease.
Does this mean that I can use C++ & C# code together, within the same project if I append the /clr flag?
I'm a little confused by this, and it'll just waste time if I went the long route of converting the C# project that I'm trying to use parts of to C++, if doing so isn't actually needed.
Basically, I answered my own question on a different topic a couple of days ago without realising that the actual code of the sample project is C#:
Obtaining Current Network Rate
Can anybody give me a firm clarification to whether I understand this correctly (that I can use C# code in a C++ project with no issues, apart from the /clr switch being required)?
I'm not sure if SO is the right place to ask a question like this, so please tell me if it isn't instead of downvoting with no explanation.
Thanks.
Edit
Forgot to mention that this is a C++/CLI gameserver application DLL on Windows. If it matters, it is used on only Windows Server 2008 R2 and Windows 7.
If you use C++/CLI, then you can add references to other .net assemblies, but you do not mix C++ and C# code in the same project. What you would do is to create a new project (or add an existing one) in your solution using C#, and then add a reference to it in the C++/CLI project.
The drawback is that you need to marshal between C++ and .Net types (std::string vs System::String^), and you also need to learn the additional syntax used by C++/CLI (^, gcnew, etc.).
Further reading: Pure C++: Hello, C++/CLI
It means, that with the /clr switch, you can access assemblies (DLL or EXE) written for the .Net framework. Because such assemblies can be created with any .net language (including C#), you can use "code" written in C# from within C++, but it doesn't mean that you would be able to write C# in C++ project. Unfortunately - you can't.
You need to make a C++/CLI project in visual studio.
C++/CLI is a bit different to C++, because there is the managed stack, so memory is managed and you can avoid memory leaks (garbage collection).
Simply create a C++/CLI project and click on propietys and add a reference to your C# project, it should work :D
http://www.codeproject.com/KB/cs/ManagedCOM.aspx
I have written a library in C that I want to be able to be used in C#, C++, and Python (other languages would be nice, but not necessary for now). The library was developed in Linux and I have been able to compile it on Windows via MinGW. The problem I am having is when trying to add the .dll as a reference in a Visual Studio 2010 solution. The error I get is:
A reference to 'C:\path\to\libmylibrary.dll' could not be added. Please make sure that the file is accessible, and that it is a valid assembly or COM component.
I have spent some time trying to see if I am compiling the DLL incorrectly, but don't see anything glaring out at me. Some references I've used are this, this, and this.
If more information is needed I can provide some compilable example source code.
There are 2 ways to add a "DLL" to a C# project.
If the DLL is a CLR Assembly, meaning it is managed code that adheres to the CLR, then you can add it as a "reference".
If the DLL is NOT a CLR Assembly, you can load the code manually using the P/Invoke structure. There's a lot of online documentation on P/Invoke. It is messy, but it works. You need to declare each DLL entry function using the [DllImport] attribute, and load the DLL manually. Search SO for p/invoke.
Based on your error message, you are trying to load a plain DLL as an CLR DLL. That means you'll have to figure out how to use P/Invoke.
I would like to add some external .dll libraries e.g. glut32.dll (but it's only example) in Visual Studio 2008, using C#.
Can you please tell me what should I do step by step?
I am a little bit confused cause I found a lot of solutions to add dll files, but they significantly differ.
Some of them add dll's only using code, some using properties in vs, add references and in other tutorials there is about registering dlls in system.
But how to put it all together?
There are different kinds of DLLs, you'll need to treat them differently when you use them in a C# project. The 3 main kinds are:
DLLs that contain unmanaged code and were designed to be used by a program written in unmanaged code. You cannot use such a DLL directly, there is no way to add a reference to them in a C# project. You must use P/Invoke, the [DllImport] attribute is required to declare the exported functions in the DLL. Glut32.dll is such a DLL. A very basic test you can use to see if you've got such a DLL is to run Dumpbin.exe /exports on that DLL. It lists the names of the functions that are exported.
DLLs that implement an in-process COM server. They are written in unmanaged code as well. .NET has very good support for using such servers, as long as you have a type library for them. The type library is usually embedded in the DLL, Visual Studio expects to find it when you add a project reference, either through the COM tab or the Browse tab. A very basic test is Dumpbin.exe /exports again, an in-process COM server has 4 exported functions. The DllGetClassObject function is the important one. You can view the type library embedded in the DLL with OleView.exe, File + View Typelibrary. A good example is c:\windows\system32\shell32.dll
DLLs that were created by a managed compiler. They don't contain machine code like the other types, they contain IL code and metadata. It is the native kind of DLL for managed code, you simply use Project + Add Reference to add a reference, the compiler automatically knows the types that are available in the DLL.
The first kind is the one you'll encounter a lot for DLLs in the wild. There's a lot of code written for Windows in an unmanaged language. It isn't a kind of DLL that's particularly easy to use from managed code. Glut32.dll for example has a lot of exported functions, writing a P/Invoke declaration for every single one of them is painful.
Tools you can use to help with this are SWIG and PInvoke Interop Assistant. The former is required when the DLL was written in the C++ language. C++ classes are not directly usable from a C# program, they need a wrapper written in the C++/CLI language. The latter tool is useful for DLLs written in C, including the Windows API.
Beware that those tools don't usually give you a clean and guaranteed-to-work interop solution. Declarations in unmanaged code are ambiguous, you'll need to know the exact semantics of the arguments of an unmanaged function to pick the right one. Getting the wrong one can be hard to diagnose, the best place to get help is a forum or Q+A site. Like stackoverflow.com
You can use the add reference dialog under the project menu to do that. Just go to the COM tab and add your library. Now you can verify that the classes appear in teh object browser
Right click on project in solution explorer and select add reference and then browse and select the dll.
If you wish to reference the dlls you
Right Click on References, and select add reference.
Or have a look at
How to: Add and Remove References in Visual Studio (C#)
Adding a Reference to a C# or Visual Basic .NET Project
In Solution Explorer, right-click the project node and click Add Reference.
In the Add Reference dialog box, select the tab indicating the type of component you want to reference.
Select the components you want to reference, and then click OK. Tip.