C++ CLI unable to delete the pointer passed to a dll - c#

I am writing a c# (c++ cli) wrapper to get data from a dll (Written in C++). I am passing a CStringArray * to a function in the dll which fills up an array of string back to me. I can read the contents of it. But when I try to delete the pointer created by me (I do a new and pass that pointer to the dll function), I get access voilation exception. After going multiple threads discussed in SO, I feel that this might be happening due to version difference in dll and my wrapper. The dll is built using VS 2012 and the wrapper that I am writing is developed in VS 2010. Could this be a problem? I spoke to developer of dll and he confimed that he is just added some string and not doing any allocation in the dll.
I wrote a test code (everything is vs2010) where in I have created a dll, a wrapper and test application. I can call delete without any problem.
Request you experts to confirm if this is the actual root cause of the problem. Here is the code snippet (my test code). Production code is almost the same but crashes the moment I call RemoveAll().
void MyDllWrapper::getLabels()
{
CStringArray* data = new CStringArray;
//FYI - mClass = new MyClass()
mClass->getLabels(data); //Call dll to get the data
this->m_strLabels = gcnew List<String^>;
for(int i = 0; i < data->GetCount(); i++)
{
Console::WriteLine("Added string {0}", gcnew String(data->GetAt(i)));
m_strLabels->Add(gcnew String(data->GetAt(i)));
}
data->RemoveAll(); //works fine
delete data;
}

There is no ABI support in MFC, except for MFC extension DLLS and their consumers built in the same MFC version and configuration (Unicode/MBCS, Debug/Release etc). Mixing MFC versions definitely won't work.
A better way to pass the string array to you is to use a C style interface like a VARIANT of type VT_BSTR|VT_ARRAY or a string buffer containing double-null-terminated strings.

Related

load C# dll in c++/cli and create a dll that works in unmanaged language

I have written a selenium script in C# and now I want to expose all functions and use them all in c++ code. My point is to deliver a dll to sb who wants to use this dll in pascal (delphi). The C# code is a complete code and all I want to do is to make a bridge between my C# and pascal.
I found out that pascal is an unmanaged language so C# code, which is a managed one, can not be consumed in pascal. For that reason, I started to write a c++ dll that uses my C# dll and makes a bridge between my C# and pascal code.
I've read all available topics on stackoverflow and these are what I've found useful:
expose my functions using COM
using c++/cli to communicate with my C# dll.
I started with the first one. I was able to create COM visible dll and use that in my c++ native code but I had problems with data types. I found it hard and moved on to the second option. But I'm not sure if I can wrap all my functions like that and let unmanaged languages use them.
a sample of my c# code:
namespace MainEngine
{
public static class StartMainEngine
{
public static void test_pascal(out string _result)
{
_result = "Hello World!";
}
}
}
my c++/cli code(I have referenced to my dll and visual studio shows me all functions inside my dll. So, It's not a dll import issue):
#using<ManagedLibrary.dll>
using namespace MainEngine;
char* r;
StartMainEngine::test_pascal(r);
Please guide me through this and let me know if I'm doing this in the correct way to be able to consume this dll in pascal.
It's possible using COM, CLR or IPC
Full answer you can find in this topic here

c# Call a method by memory address

I am trying to call a function at a specified memory address in c#, here is how I would go about it in C:
typedef void _do(int i);
auto doActor = (_do*)0xAAAABEEF;
doActor(1);
How do I replicate this behavior in C# if at all possible? Very new to C# all help is appreciated.
More in depth explanation of my situation: I am trying to create a tool that helps me automate certain processes within an executable. I decompiled the assembly of the main API and added my functionality (for the most part) by intercepting network packets/spoofing my own. I do not have control over the client side of things, stored in an obfuscated assembly that I can't de-/recompile. I seldomly need to call one or two functions out of this obfuscated assembly and I found the memory addresses of those relevant functions using a debugger but don't know where to go from here in c#.
The closest equivalent to a C function pointer in C# is a delegate. Delegates are managed, but you can convert one from the other with the Marshal.GetDelegateForFunctionPointer method:
public delegate void _do(int i); // the delegate type
var ptr = new IntPtr(0xAAAABEEF);
var doActor = Marshal.GetDelegateForFunctionPointer<_do>(ptr);
doActor(1);
There are limitations tied to this API, however. I suggest you take a look at the documentation.
If you're stuck with a version of .NET older than 4.5, you're going to have to use a different version of GetDelegateForFunctionPointer:
var doActor = (_do)Marshal.GetDelegateForFunctionPointer(ptr, typeof(_do));

Is it possible to call a R statistics function to optimize C# function

I want to know if it's possible to call r statistics optimization function (here I want to use regnoud) from C# while the function to be optimized is written in C#.
I found RDotNet library but with it i cannot evaluate the C# function from R.
In other terms, the problem is that R while optimizing needs to evaluate the function but he cannot do it because the function is in the C# code.
is there any solution like using .dll or other libraries?
thanks.
I have done this before using a somewhat convoluted approach but it works!
First, you will need to create a C# DLL containing your function. You can do this in visual studio by selecting "class library" as the option when creating a new project. The code in the .cs file should look like this
namespace MyNamespace
{
//expose an interface with functions to be called from R
public interface MyInterface
{
string MyFunction(string name);
}
//create a class that implements the above interface
public class MyClass : MyInterface
{
public string MyFunction(string name)
{
return "Hello " + name;
}
}
}
Now compile your project and you will get a C# DLL. This DLL is a managed DLL which is different from a native C/C++ DLL. It cannot be directly consumed from non .Net languages and so needs to be exposed as a COM object. You can do this in one of two ways
In Visual Studio, you can go to the project properties, click on "Assembly information" button under "Application" tab and select the checkbox that says "Make assembly COM visible".
Alternatively, you can use regasm.exe which can be found in the .net installation folder to register the DLL as a COM component. Here is a link describing this process. http://msdn.microsoft.com/en-us/library/tzat5yw6(v=vs.71).aspx. The command is usually "regasm myTest.dll /tlb:myTest.tlb"
The COM registration process will now have created a .tlb file in the same folder as your DLL. Keep this .tlb file. We will need it in the next step
The next step is to create a C++ DLL which can call the COM DLL. This step is needed because R can call a C++ DLL directly but cannot call COM directly (correct me if I am wrong or skip this step if you know a better way to call COM from R). The code for the C++ DLL in dllmain.cpp is shown below (make sure to scroll to see the full code)
#include "stdafx.h"
#include <iostream>
//import the .tlb file create by COM registration
#import "path_to_Dll\MyDll.tlb" named_guids raw_interfaces_only
void _cdecl MyCPPFunction(char ** strName)
{
//Initialize COM
HRESULT hr = CoInitialize(NULL);
//create COM interface pointer
MyNamespace::MyInterfacePtr myPtr;
//create instance of COM class using the interface pointer
HRESULT hr2 = myPtr.CreateInstance(MyNamespace::CLSID_MyClass);
//create variable to hold output from COM.
BSTR output;
//call the COM function
myPtr->MyFunction(_bstr_t(strName[0]), &output);
//convert the returned BSTR from .net into char*
int length = (int) SysStringLen(output);
char *tempBuffer;
tempBuffer = (char *) malloc(1 + length);
WideCharToMultibyte(CP_ACP, 0, output, -1, tempBuffer, length, NULL, NULL);
tempBuffer[length] = '\0';
//release interface
myPtr->Release();
//uninitialize COM
if(hr == S_OK)
CoUninitialize();
//set output in input for returning to R (this is weird but the only way I could make it work)
strName[0] = tempBuffer;
}
Now compile your project and you will get a C++ DLL. We are almost there now! Dont give up yet :). Now, you have a C# DLL exposed as a COM object and a C++ DLL that can call this COM object. The final step is to call the C++ function from R. Here is the R code to do that
#load C++ DLL
dyn.load("path_to_C++_DLL")
#call function in C++ DLL and pass in a test name.
# The C++ DLL will in turn call the C# function
output <- .C("MyCPPFunction", as.character("Peter"))
#print output
print(output)
And you should see "Hello Peter" displayed from C# in the R console! One very important point to note.
Always, compile the COM DLL using "any CPU" option. Always compile the C++ DLL to match your R installation! For example, if you have 32 bit R installed, then make sure you compile the C++ DLL as 32 bit DLL. If you have 64 bit R installed and want to use it, then make sure you compile your C++ DLL as a 64 bit DLL. Best of luck!
If I understand your need clearly, you have a an optimisation problem with a C# calling R calling back C#.
I do not think there is a way to set up a callback function ("function pointer", "delegate" as they can be called depending on who you talk to) in R.NET currently. I am likely to have very similar needs and may contribute this to R.NET in the future, if I can allocate the time.
Meanwhile, if it is acceptable to have things such that you work from R calling C#, i.e. R is the entry point of your application, this is definitely doable using the rClr
package. I have colleagues doing optimisation and MCMC analysis of a model written in C#. One tutorial is a very simplified but realistic case of optimisation from R using C#.
http://www.codeproject.com/Articles/25819/The-R-Statistical-Language-and-C-NET-Foundations
Check out something like this. Now I don't know much about C# so if I say anything that is impossible please don't hurt me:
Try to save the function that you want optimized as a character in C#, and send it to R using this StatConnector library (I have some limited experience with it.) Let's say you saved the equation as 'z' within R, you can then call your R scripts with 'get(z)' as one of the variables.

How to call a C++ exported function from C#, in another process?

I haven't found anything useful related to this problem after some serious google lurking, so I'll ask it here.
I have a program that's made in C# that injects a DLL into another process, fairly trivial. It Calls CreateRemoteThread and LoadLibrary from kernel32.dll with [DllImport].
My DLL once loaded then waits for authentication from the C# program, due to security reasons, I can't have this data transferred using sockets. So I have my DLL export a function that's planned to be called from the C# program with authentication data.
The exported function takes two arguments, it is as follows :
extern "C" __declspec(dllexport) void DoStuff( const char* ccString1, const char* ccString2 ){
// Do stuff
}
Since as the DLL isn't in the same address space as the C# program, I can't use [DllImport] to get and the call the exported function.
My second idea was to use CreateRemoteThread to call the function, though that can only be passed 1 argument whereas I need two, it'd also be difficult because I'd need to call the return of GetProcAddress, I can't simply call by exported function directly.
So, how would I go about achieving this?
Thanks
[DllImport] is the same as GetProcAddress. C# does not load the DLL until the first call, so the .NET can do the security checks before calling the DLL.
If you don't trust the DLL at all, then it's better to split de C# program in two. One program connected via Remoting/WCF/IPC to the second one, and the second one connects to the C DLL via DllImport. This solution is typically used when you don't trust C DLL stability or memory allocation because the second program (the one that call de C DLL) can be restarted without restarting the main program. Example of this pattern: some windows drivers (with the exception that they don't use C# at this time).
You could use Non-persisted memory-mapped files to exchange data between the application and the DLL.

Writing a C++ DLL that a C# .NET Application can call?

This is the situation. I am writing a backend application in C++ and my colleagues are using C# for the frontend. Basically, my backend application does image processing on images received from the C# frontend and returns a text file with data about the image.
What we were doing earlier was writing the images to disk and calling the C++ application with the file path of the image as a parameter. However, this writing/reading from disk has become a bottleneck, so we are wanting to convert the C++ application to a DLL.
At the basic level, what I want is to expose a single method from my C++ application to the C# one through a DLL (the C# application is web-based):
int ProcessImage(System::Bitmap^ image, System::String ^results)
How can I go about doing this? I am using VC++ Express 2008 and my C++ code currently compiles with CLR (although I have mixed a lot of native C++ code inside).
I have been looking around on the web, but am still stuck on how to do this. I think a C++/CLI DLL is the best option, but how do I do this?
Writing a DLL in C/C++ for .Net interoperability
If you label your C++ function as a "C" function, then it can be called by PInvoke.
Your C function will look like this:
extern "C" __declspec(dllexport) int Test() {
return 1;
}
Your C# reference will be like this:
[DllImport("test.dll")]
public static extern int Test();
If you C++ function is an instance member, then you can still do it but it requires some tricks.
I finally figured it out. What you need to do is:
In your C++ project, set the option in Visual C++ to compile with clr pure, which makes the project a C++/CLI one
In your C++ project, expose methods by creating a public ref class:
public ref class Interop
{
public:
//! Returns the version of this DLL
static System::String^ GetVersion() {
return "3.0.0.0";
}
//! Processes an image (passed by reference)
System::Int32^ Process(Bitmap^ image);
}
In a C# program, add a reference to the C++ DLL you compiled
In the C# program, call these methods (i.e. Interop::Process(myBitmapInCS))
I believe this method is called "implicit P/Invoke"
Hope this helps!

Categories