How to Call C++ Native Properity from C# - c#

I'm not that good in C++
but,..
For example I have this
#define GETSomthing_API __declspec(dllexport)
extern GETSomthing_API int nGetSomthing;
And the method I want to import like this
GETSomthing_API int GetSomthing(const char* szConfigPath, char *A, int B)
How Can I call this from C# ?
Beside,
I think my problem is with the parameter type (const char* ) in C++ side, what is the equal type in C# for it! const char*
Thanks,

How to call C++ code from C#
or
Calling C++ function from C#
Using: [DllImport("xxx.dll")] xxx.dll is compile by C++
Hope this help.

There are a couple of ways for calling into native code from C#. The easiest is probably to use P/Invoke.
Say your function is like :
extern "C" int nGetSomeThing(void);
and it is compiled into a YourDllName.dll file, you can use P/Invoke to directly call into the unmanaged code in the following way from C# code :
public static class interop
{
[DllImport("YourDllName.dll")]
static extern public int nGetSomeThing(void);
}
...
interop.nGetSomething() // call to the native function
Refer : http://msdn.microsoft.com/en-us/library/aa288468%28VS.71%29.aspx.
If you have a lot of functions with complex signatures, you should probably go for an interop layer in C++/CLI.
Refer : http://www.codeproject.com/Articles/19354/Quick-C-CLI-Learn-C-CLI-in-less-than-10-minutes

I just added __cplusplus check and it worked!
#ifdef __cplusplus
extern "C" {
endif
GETSomthing_API char* GetAgentId(const char* szConfigPath, char *szA, int ASize);
ifdef __cplusplus
}

Related

How to access constant values in an unmanaged dll

I have an unmanaged dll, inside which there is a constant value as the following:
#define ProtocolVersion 1
How can I access this value in C#?
p.s.: I checked this post but it didn't work.
This is a preprocessor define and will not be compiled to the DLL. You can however create a C/C++ function returning this value and call it from C#. Something like:
extern "C" __declspec(dllexport) int GetProtocolVersion()
{
return ProtocolVersion;
}
and in C#:
[DllImport("MyDll")]
extern int GetProtocolVersion();

How to import a c++ custom class into c# unity [duplicate]

I have a dll that was written in c++, I need to use this dll in my c# code. After searching I found that using P/Invoke would give me access to the function I need, but these functions are defined with in a class and use non-static private member variables. So I need to be able to create an instance of this class to properly use the functions. How can I gain access to this class so that I can create an instance? I have been unable to find a way to do this.
I guess I should note that the c++ dll is not my code.
There is no way to directly use a C++ class in C# code. You can use PInvoke in an indirect fashion to access your type.
The basic pattern is that for every member function in class Foo, create an associated non-member function which calls into the member function.
class Foo {
public:
int Bar();
};
extern "C" Foo* Foo_Create() { return new Foo(); }
extern "C" int Foo_Bar(Foo* pFoo) { return pFoo->Bar(); }
extern "C" void Foo_Delete(Foo* pFoo) { delete pFoo; }
Now it's a matter of PInvoking these methods into your C# code
[DllImport("Foo.dll")]
public static extern IntPtr Foo_Create();
[DllImport("Foo.dll")]
public static extern int Foo_Bar(IntPtr value);
[DllImport("Foo.dll")]
public static extern void Foo_Delete(IntPtr value);
The downside is you'll have an awkward IntPtr to pass around but it's a somewhat simple matter to create a C# wrapper class around this pointer to create a more usable model.
Even if you don't own this code, you can create another DLL which wraps the original DLL and provides a small PInvoke layer.
Marshal C++ Class and use the PInvoke
C++ Code ,ClassName.h
class __declspec(dllexport) CClassName
{
public:
CClassName();
~CClassName();
void function();
};
C++ Code, ClassName.cpp
CClassName::CClassName()
{
}
CClassName::~CClassName()
{
}
void CClassName::function()
{
std::cout << "Bla bla bla" << std::endl;
}
C++ Code, ClassNameCaller.h file for the caller function
#include "ClassName.h"
#ifdef __cplusplus
extern "C" {
#endif
extern __declspec(dllexport) CClassName* CreateClassName();
extern __declspec(dllexport) void DisposeClassName(CClassName* a_pObject);
extern __declspec(dllexport) void function(CClassName* a_pObject);
#ifdef __cplusplus
}
#endif
C++ Code, ClassNameCaller.cpp file for the caller function
#include "ClassNameCaller.h"
CClassName* CreateClassName()
{
return new CClassName();
}
void DisposeClassName(CClassName* a_pObject)
{
if(a_pObject!= NULL)
{
delete a_pObject;
a_pObject= NULL;
}
}
void function(CClassName* a_pObject)
{
if(a_pObject!= NULL)
{
a_pObject->function();
}
}
C# code
[DllImport("ClassNameDll.dll")]
static public extern IntPtr CreateClassName();
[DllImport("ClassNameDll.dll")]
static public extern void DisposeClassName(IntPtr pClassNameObject);
[DllImport("ClassNameDll.dll")]
static public extern void CallFunction(IntPtr pClassNameObject);
//use the functions
IntPtr pClassName = CreateClassName();
CallFunction(pClassName);
DisposeClassName(pClassName);
pClassName = IntPtr.Zero;
Here is a sample how to call C++ class method from VB - for C# you only have to rewrite the sample program in Step 4.
You may need to write an intermediary DLL (in C++, perhaps) that handles this for you and exposes the interface you need. Your DLL would be in charge of loading the 3rd party DLL, creating an instance of this C++ object, and exposing its member functions as needed via whatever API you design. You would then use P/Invoke to get at your API and cleanly manipulate the object.
Note: For the API of your DLL, try keeping the data types limited to primitives (long, int, char*, etc.) to prevent module boundary issues.
The way I've done this is by creating a thin Managed C++ wrapper around my unmanaged C++ DLL. The managed wrapper contains "proxy" classes that wrap around the unmanaged code exposing the interface that's needed by the .NET application.
This is a bit of double work but it allows quite seamless operation in normal environments. Things do get trickier with dependencies in some circumstances (such as ASP.NET) but you will probably not run into that.
I agree with JaredPar.
Creating instances of unmanaged classes in managed code should not be possible.
Another thing is - if you could recompile the DLL in managed C++ or make a COM component out of it, it would be much easier/

Reading string from C# managed code to C++ wchar* [] getting AccessViolation

The question is easy, Want to read a string from managed C# code to my unmanaged C++ code in WCHAR* [].
The C function is:
extern "C" __declspec(dllexport) int __cdecl myfunc(int argc, WCHAR* argv[])
and in C# I imported the DLL:
[DllImport("mydll.dll", CharSet = CharSet.Auto, SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
public static extern int myfunc(int argc, [MarshalAs(UnmanagedType.LPTStr)] StringBuilder str);
I run, but when I tried to read the string in my C++ code I get AccessViolationException : Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
What is the correct way to do this and vice versa (i.e. passing a string from C++ unmanaged to C# managed code)?
Help Appreciated.
Thanks
It seems that your C function expects an array of strings, and you're passing a single string instead.
I haven't used P/Invoke myself, but this question might provide some insight.
I am not sure about C# to C++ but i can help you out in your C++ to C# problem.
Export the function from C++ code like this:
DllExport std::string MyFunction( std::string MyParameter) ;
This can be imported in your C# code as:
[DllImport("DLLName.dll", EntryPoint = "MyFunction", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
[return: MarshalAs(UnmanagedType.LPStr)]
public static extern string MyFunction([System.Runtime.InteropServices.InAttribute()] [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)] string MyParameter);
Now, in your C# code the function "MyFunction" will take in a string and return a string. You can then call MyFunction and the operations can be carried out.
If you are using a WCHAR*, perhaps you should try marshalling as UnmanagedType.LPWStr instead to avoid passing half as much memory as expected?
The documentation on Default Marshaling for Strings should provide you with more details.

C++ from C#: C++ function (in a DLL) returning false, but C# thinks it's true!

I'm writing a little C# app that calls a few functions in a C++ API. I have the C++ code building into a DLL, and the C# code calls the API using DllImport. (I am using a .DEF file for the C++ DLL so I don't need extern "C".)
So far the API has one function, which currently does absolutely nothing:
bool Foo()
{
return false;
}
In C#, I have the following:
public class FooAPI
{
[DllImport("Foo.dll")]
public static extern bool Foo();
}
...
bool b = FooAPI.Foo();
if (!b)
{
// Throw an exception
}
My problem is that, for some reason, b is always evaluating to TRUE. I have a breakpoint on if (!b) and the debugger reports it as 'true', irrelevant of whatever the C++ function is returning.
Is the C# bool the same as the C++ bool? Though even if this wasn't the case, I still don't get how it would find the return value to be 'true' :)
Can anyone help me with this bizarre discrepancy?
Thanks in advance!
Try [return: MarshalAs (UnmanagedType.I1)]. By default, C# interop marshals C# bool as the Win32 BOOL, which is the same as int, while C++ bool is one byte AFAIR. Thus, C#'s default marshaling expects the return value to be a BOOL in the eax register, and picks up some non-zero garbage because C++ bool is returned in al.
Your code snippet as posted cannot work. If this was compiled with a C++ compiler then the function name would be ?Foo##YA_NXZ and your C# code could never find it. The calling convention is important too, it is not the default (CallingConvention.StdCall) unless you tell the compiler. And somewhere you should have told the linker to export the function.
Start by declaring the exported function so it is compatible with default P/Invoke attributes:
extern "C" __declspec(dllexport)
bool __stdcall Foo() {
return false;
}
Next problem is that the C++ compiler uses only one byte to store a bool. The machine code generated for your return statement is:
013D138E xor al,al
The P/Invoke marshaller will however assume it is a 32-bit integer and check the value of the eax register. Either declare the return type of the function as int or BOOL or use a [return: MarshalAs(UnmanagedType.U1)] attribute in the C# declaration.
I used signed int.
C++ code
extern "C" __declspec(dllexport) signed int TestDouble(double* output)
{
*output = 1.3;
return true;
}
C# code
[DllImport("abc.dll", EntryPoint = "TestDouble", CallingConvention = CallingConvention.Cdecl)]
public static extern bool TestDouble(out double output);

using a class defined in a c++ dll in c# code

I have a dll that was written in c++, I need to use this dll in my c# code. After searching I found that using P/Invoke would give me access to the function I need, but these functions are defined with in a class and use non-static private member variables. So I need to be able to create an instance of this class to properly use the functions. How can I gain access to this class so that I can create an instance? I have been unable to find a way to do this.
I guess I should note that the c++ dll is not my code.
There is no way to directly use a C++ class in C# code. You can use PInvoke in an indirect fashion to access your type.
The basic pattern is that for every member function in class Foo, create an associated non-member function which calls into the member function.
class Foo {
public:
int Bar();
};
extern "C" Foo* Foo_Create() { return new Foo(); }
extern "C" int Foo_Bar(Foo* pFoo) { return pFoo->Bar(); }
extern "C" void Foo_Delete(Foo* pFoo) { delete pFoo; }
Now it's a matter of PInvoking these methods into your C# code
[DllImport("Foo.dll")]
public static extern IntPtr Foo_Create();
[DllImport("Foo.dll")]
public static extern int Foo_Bar(IntPtr value);
[DllImport("Foo.dll")]
public static extern void Foo_Delete(IntPtr value);
The downside is you'll have an awkward IntPtr to pass around but it's a somewhat simple matter to create a C# wrapper class around this pointer to create a more usable model.
Even if you don't own this code, you can create another DLL which wraps the original DLL and provides a small PInvoke layer.
Marshal C++ Class and use the PInvoke
C++ Code ,ClassName.h
class __declspec(dllexport) CClassName
{
public:
CClassName();
~CClassName();
void function();
};
C++ Code, ClassName.cpp
CClassName::CClassName()
{
}
CClassName::~CClassName()
{
}
void CClassName::function()
{
std::cout << "Bla bla bla" << std::endl;
}
C++ Code, ClassNameCaller.h file for the caller function
#include "ClassName.h"
#ifdef __cplusplus
extern "C" {
#endif
extern __declspec(dllexport) CClassName* CreateClassName();
extern __declspec(dllexport) void DisposeClassName(CClassName* a_pObject);
extern __declspec(dllexport) void function(CClassName* a_pObject);
#ifdef __cplusplus
}
#endif
C++ Code, ClassNameCaller.cpp file for the caller function
#include "ClassNameCaller.h"
CClassName* CreateClassName()
{
return new CClassName();
}
void DisposeClassName(CClassName* a_pObject)
{
if(a_pObject!= NULL)
{
delete a_pObject;
a_pObject= NULL;
}
}
void function(CClassName* a_pObject)
{
if(a_pObject!= NULL)
{
a_pObject->function();
}
}
C# code
[DllImport("ClassNameDll.dll")]
static public extern IntPtr CreateClassName();
[DllImport("ClassNameDll.dll")]
static public extern void DisposeClassName(IntPtr pClassNameObject);
[DllImport("ClassNameDll.dll")]
static public extern void CallFunction(IntPtr pClassNameObject);
//use the functions
IntPtr pClassName = CreateClassName();
CallFunction(pClassName);
DisposeClassName(pClassName);
pClassName = IntPtr.Zero;
Here is a sample how to call C++ class method from VB - for C# you only have to rewrite the sample program in Step 4.
You may need to write an intermediary DLL (in C++, perhaps) that handles this for you and exposes the interface you need. Your DLL would be in charge of loading the 3rd party DLL, creating an instance of this C++ object, and exposing its member functions as needed via whatever API you design. You would then use P/Invoke to get at your API and cleanly manipulate the object.
Note: For the API of your DLL, try keeping the data types limited to primitives (long, int, char*, etc.) to prevent module boundary issues.
The way I've done this is by creating a thin Managed C++ wrapper around my unmanaged C++ DLL. The managed wrapper contains "proxy" classes that wrap around the unmanaged code exposing the interface that's needed by the .NET application.
This is a bit of double work but it allows quite seamless operation in normal environments. Things do get trickier with dependencies in some circumstances (such as ASP.NET) but you will probably not run into that.
I agree with JaredPar.
Creating instances of unmanaged classes in managed code should not be possible.
Another thing is - if you could recompile the DLL in managed C++ or make a COM component out of it, it would be much easier/

Categories