I have an C++ DLL in which the following functions are exported.
double getDouble(std::wstring filename, std::string ID, status &stCode);
int getInt(std::wstring filename, std::string ID, status &stCode);
float getFloat(std::wstring filename, std::string ID, status &stCode);
string getString(std::wstring filename, std::string ID, status &stCode);
int* getIntArray(std::wstring filename, std::string ID, status &stCode);
float* getFloatArray(std::wstring filename, std::string ID, status &stCode);
string* getStringArray(std::wstring filename, std::string ID, status &stCode);
where status is of enum type...
Now I want to use this DLL in my C#.NET app... Can anyone tell me how do i delclare the respected methods in C# and can make a call to this methods.... Thanks in advance...
[DllImport("external.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
public static extern MbStatus queue_accept(
int reader,
[MarshalAs(UnmanagedType.LPStr)] string status);
Lookup the parameters for the DllImport attribute. Depending on your DLL those might need to be adjusted!
Side note: I usually wrap the external dll in an interface and a code layer to decouple it for tests and load it with dependency injection. I also don't change the naming conventions.
public interface IExternalDllInterop
{
MB_STATUS queue_accept(int reader, string status);
}
public class AmbInterop : IAmbInterop
{
public MbStatus queue_accept(int reader, string status)
{
return StaticAmbInterop.mb_queue_accept(reader, message, status);
}
}
Yes. You can. Actually, not std::string
, std::wstring
, any standard C++ class or your own classes can be marshaled or instantiated and called from C#/.NET. You will need to write a wrapper class for each of the C++ class before you can marshal them in .NET.
The basic idea of instantiating a C++ object from .NET world is to allocate exact size of the C++ object from .NET, then call the constructor which is exported from the C++ DLL to initialize the object, then you will be able to call any of the functions to access that C++ object, if any of the method involves other C++ classes, you will need to wrap them in a C# class as well, for methods with primitive types, you can simply P/Invoke them. If you have only a few methods to call, it would be simple, manual coding won't take long. When you are done with the C++ object, you call the destructor method of the C++ object, which is a export function as well. if it does not have one, then you just need to free your memory from .NET.
Here is an example.
public class SampleClass : IDisposable
{
[DllImport("YourDll.dll", EntryPoint="ConstructorOfYourClass", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.ThisCall)]
public extern static void SampleClassConstructor(IntPtr thisObject);
[DllImport("YourDll.dll", EntryPoint="DoSomething", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.ThisCall)]
public extern static void DoSomething(IntPtr thisObject);
[DllImport("YourDll.dll", EntryPoint="DoSomethingElse", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.ThisCall)]
public extern static void DoSomething(IntPtr thisObject, int x);
IntPtr ptr;
public SampleClass(int sizeOfYourCppClass)
{
this.ptr = Marshal.AllocHGlobal(sizeOfYourCppClass);
SampleClassConstructor(this.ptr);
}
public void DoSomething()
{
DoSomething(this.ptr);
}
public void DoSomethingElse(int x)
{
DoSomethingElse(this.ptr, x);
}
public void Dispose()
{
Marshal.FreeHGlobal(this.ptr);
}
}
For the detail, please see the below link,
(I am the author of the SDK tool)
Once you have the C# wrapper class for your C++ class ready, it is easy to implement ICustomMarshaler
so that you can marshal the C++ object from .NET.
http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.icustommarshaler.aspx
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.