I am new to Visual Studio 2010,
I have the DLL written with C# , and it is working with VB.NET , Now I want to use it with VC++, Can you help me ?
If you are planning on using .NET extensions in your VC++ project, you just need to add a reference to your C# DLL in your VC++ project.
If you're planning to use pure C++, you'll need to change your C# DLL to be COM-Visible, and generate a typelib that you'll import in your C++ project.
You can access functions from native DLL (written in C++) from .NET using PInvoke. To use managed DLL from native code (eg. call C# method from C++ code) you have to wrap managed code in COM component and use that COM object from C++
Going the other way is easy using P/invoke. Calling managed code from unmanaged is tricker. One good option is COM, but there is an alternative. Robert Giesecke has published an excellent project that allows you to expose managed methods as unmanaged DLL exports.
It's very simple to use. You simply download the Visual Studio template, create a project based on that, add your code, and mark exports with the DllExport attribute.
Or you can create Manager C++ DLL that will reference and implement all or custom objects from C# DLL.
After than you can create dllexport methods in your MCPP DLL.
And then you can access C# DLL thru MCPP DLL using LoadLibrary(...)/GetProcAddress(...) methods.
Example:
using namespace System;
using namespace System::Windows::Forms;
__declspec(dllexport) LPVOID GetPluginInterface()
{
return (IWithExecuteCommandMethod*)&theApp;
}
bool CClass::ExecuteCommand()
{
if(Threading::Thread::CurrentThread->TrySetApartmentState(System::Threading::ApartmentState::STA))
{
Flatbed::SomeDialog ^pDialog=gcnew Flatbed::SomeDialog();
pDialog->ShowDialog();
}
else
{
Threading::Thread ^pDialog=gcnew Threading::Thread(gcnew Threading::ThreadStart(ThreadProc));
pDialog->SetApartmentState(Threading::ApartmentState::STA);
pDialog->Start();
}
return false;
}
Related
I'm trying to make my first c# dll.
I want to be able to call it's methods/functions from ruby with win32API.
I have made this dll:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ClassLibrary1
{
public class Class1
{
public int PropA = 10;
public void Multiply(Int32 myFactor)
{
PropA *= myFactor;
}
}
}
I compiled it with Visual Studio 2010 and got my ClassLibrary1.dll file.
Now for the ruby part i tried this:
f = "c:/path_to_file/ClassLibrary1.dll"
mult = Win32API.new(f,"Multiply",["I"],"I")
But, i get the following error:
Error: #<RuntimeError: (eval):0:in `initialize': GetProcAddress: Multiply or MultiplyA
To be honest, I never created a dll, nor do I have experience with c#. I just wanted to get started. I have used many dll's with Ruby via win32API before (user32 mostly).
I guess my dll is not ok?
Regards,
To consume functions from DLLs as done in a Win32 context, these functions need to be export-visible from the DLL. These functions are usually flagged with dllexport and will show up in the export table of a DLL. You can verify that user32 and other Win32 DLLs do this by using a utility such as dumpbin (MSDN).
dllexport, dllimport # MSDN
Unfortunately, .NET doesn't have immediate support for making functions export-visible, only for bringing in such functions via the DllImport (MSDN) Attribute.
COM is the easiest way to consume code written within .NET from a non-.NET environment, but if you must use the lower level bindings, you can make an intermediate DLL in C, C++/CLI, or any other language and framework combination that can write export headers to a dll, to call your .NET code.
Also, A few articles exist on making this happen via post-compilation automation or other workarounds, here are a few for your reference.
How to Automate Exporting .NET Function to Unmanaged Programs # CodeProject
Unmanaged Exports # Google Sites
DllExport - Provides C-style exports for pure .NET assemblies
Without doing anything extra, the DLL created is an Assmebly intended to be run inside the .Net runtime (the CLR).
You can expose it through Com as described in the related question: Can Ruby import a .NET dll? which
Has anyone worked on calling a C# module from C module. I tried searching on internet but didn't find good examples. Though lot of sites say something like using COM interop but couldn't find a proper example or article explaining it though.
If someone can help me on this, it would be great
Thanks,
Sveerap
There is more than just COM interop if you want to call into managed code from C or C++. The are also the following lesser known methods (taken from MSDN FAQ):
How do I call a .NET assembly from native Visual C++?
There are basically four methods to
call .NET assembly from native VC++ code:
CLR Hosting API: Native VC++ module calls CLR Hosting APIs to host CLR, load and call the .NET assembly (sample code: CppHostCLR).
COM Interop: If the .NET assembly can be exposed as a COM component, native VC++ module can call into the .NET assembly through .NET – COM interop (sample code: CppCOMClient).
Reverse PInvoke: The managed code calls native code passing a delegate that the native code can call back (sample code: CSPInvokeDll).
C++/CLI: If the module containing native VC++ code is allowed to enable CLR, the native VC++ code can call
.NET assembly directly (sample code: Consuming C# Library in native C or C++ using C++/CLI)
Here is a solution. The solution allows calling a C# function from C by decorating your function with [DllExport] attribute (opposite of P/Invoke DllImport).
https://sites.google.com/site/robertgiesecke/Home/uploads/unmanagedexports
C# code
class Test
{
[DllExport("add", CallingConvention = CallingConvention.StdCall)]
public static int Add(int left, int right)
{
return left + right;
}
}
C code
int main()
{
int z = add(5,10);
printf("The solution is found!!! Z is %i",z);
return 0;
}
As #iceflow19 commented below:
The author of the link provides a CLR IL preprocessor as an added step during compilation. Since assemblies use the same binary container format (DLL) on windows, if you manually add the .Net functions offsets in IL to the vtable (the dll's list of exports), Windows is smart enough to invoke the CLR to run that code when called from C. However there is overhead. It's an unadvertised feature. This is how mixed managed libraries in C++/CLI work. To use it just add it through Nuget. The extra target added in your MSBuild project file will provide for the IL preprocessing step
You could expose your C# module as COM:
http://www.codeproject.com/KB/cs/ManagedCOM.aspx
Best method of calling managed code(c#) from unmanaged C++
http://www.codeproject.com/KB/COM/cominterop.aspx
There is also the option of building native libraries from C# code using CoreRT and call them from C.
Here is an example.
Edit: CoreRT has moved to runtimelab feature NativeAOT. Updated link.
Do I have to create a C# DLL to call C++ DLL or I can call it directly from my C# application?
You can call it directly with PInvoke and the DllImport attribute. Assuming, of course, that it has standard C entry points, not compiler-specific C++ entry points.
Unless you were talking about C++/CLI, in which case you would reference the .NET DLL exactly as you would reference any other .NET DLL.
You can call a Win32 navite dll directly from your code using P/Invoke.
http://msdn.microsoft.com/en-us/magazine/cc164123.aspx
I am wrote a visual c++ win32 console app, and i wrote it and tested it in
win32 console project
. then i switch to
win32 project
and imported all the source files and created a dll for it. by mark the class i want to export as
#define DllExport __declspec( dllexport )
class DllExport theClass {
}
it works and the dll is generated. then i created a another c# project and want to add the dll to the project. by reference->add reference-> browser. then i select that dll.
then it is gives me an error
a reference to the '''''''.dll could
not be added. please make sure that
the file is accessible, and that is a
valid assembly or com component.
anyone knows where i did wrong to generate/import the dll?
thanks
The Add Reference dialog can only work for DLLs that contain metadata (managed code) or a type library (a COM server). Your DLL doesn't fit that bill, you can only use the [DllImport] attribute in C# code to use the P/Invoke marshaller to call an unmanaged DLL entrypoint.
That can not be a native C++ class, like you are trying to do, there is no reliable mechanism for managed code to allocate unmanaged memory and call the constructor (and destructor) of a native C++ class. Short from the difficulty of finding the constructor and destructor code, there is no way for the P/Invoke marshaller to know the size of the object. The C++ language doesn't generate the metadata necessary to know this required information.
If you want to pursue P/Invoke then write an plain global function, decorated with extern "C", __declspec(dllexport) and (optionally) __stdcall.
If you want to export a C++ class then the only avenue is using the C++/CLI language and write a "ref class" wrapper for the native C++ class.
Or you could write a COM coclass, the universal glue in Windows. Very well supported by .NET, probably not something you want to pursue if you never wrote COM code before. ATL is the best way to get one going.
I have a C++ DLL that needs to call a function (pass a value, return a value) in a C# class library.
Is my only option to give the C# DLL a COM interface and call it from C++ with IDispatch?
Is this the best method?
Couple of options available for you here
Use a mixed mode C++/CLI assembly as a bridge between the C++ and C# DLL
Use the a COM bridge by exposing several of the key C# types as COM objects. This can then be accessed via the C++ code by normal COM semantics
This project Creates dll exports for static methods in classes. You could then call a C# static method from unmanaged code.
One approach that would work would be to call it though COM. You can use the Regasm tool to create the COM wrapper.
It's not the only option.
You could also compile your C++ DLL as a managed DLL.
You could host your C# DLL as a service and remote into it.