Passing argument to c# callback from c++ - c#

Below is my code in c#...
here callback is too implemented in c# only.
i want a callback from c++ dll
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
class Program
{
// [DllImport("C:/Users/kool/Documents/Visual Studio 2010/Projects/DLL/Debug/DLL.dll", CallingConvention = CallingConvention.Cdecl)]
static void Main(string[] args)
{
function1(function2); // i want thia function2 to be fetched from ++ dll
}
public delegate void fPointer(); // point to every functions that it has void as return value and with no input parameter
public static void function1(fPointer ftr)
{
fPointer point = new fPointer(ftr);
point();
}
public static void function2()
{
Console.WriteLine("Bla");
}
}
i will createa a dLL from where i will send function2 to
function1(function2);
how can i implement it??

One way is exporting the C# assembly as a type library and using it from C++ as if it were a COM component.
Use TlbExp.exe in the Visual Studio command prompt to export the C# assembly as a type library. Then register the type library with RegAsm.exe. Then in the C++ code use the #import directive to import the type library. You can now use the C# classes from C++ as if they were COM classes.
For more detail see: http://msdn.microsoft.com/en-us/library/ms172270.aspx
Edit: Sorry, which is it that you want to do: use C++ from C#, or use C# from C++?
Either one is possible. The link above explains how to use C# from C++. This one explains how to use C++ from C#: http://msdn.microsoft.com/en-us/library/z6tx9dw3.aspx

You can send pointer to your managed .net function and call it from unmamaged code (callback).
Detail here http://habrahabr.ru/post/130690/ (use google to translate it from russian if needed, but you need to look at last two code example).
Also check your code calling - it should comply on both managed and unmanaged sides (use __stdcall in C-code and CallingConvention = CallingConvention.Cdecl in DllImport attribute).

Related

Access a function present in C# dll using Python

I want to access a function my_function() present in a c# file which is compiled into a .net dll - abc.dll.
C# file
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Test
{
public class Class1
{
public string my_function()
{
return "Hello World.. :-";
}
}
}
After compiling the above code to abc.dll
Using the below python trying to access my_function()
import ctypes
lib = ctypes.WinDLL('abc.dll')
print lib.my_function()
Above code throws error
lib.my_function()
Traceback (most recent call last):
File "", line 1, in
File "C:\Anaconda\lib\ctypes__init__.py", line 378, in getattr
func = self.getitem(name)
File "C:\Anaconda\lib\ctypes__init__.py", line 383, in getitem
func = self._FuncPtr((name_or_ordinal, self))
AttributeError: function 'my_function' not found
You haven't made the function visible in the DLL.
There are a few different ways you can do this. The easiest is probably to use the unmanagedexports package. It allows you to call C# functions directly like normal C functions by decorating your function with [DllExport] attribute, like P/Invoke's DllImport. It uses part of the subsystem meant to make C++/CLI mixed managed libraries work.
C# code
class Example
{
[DllExport("ExampleFunction", CallingConvention = CallingConvention.StdCall)]
public static int ExampleFunction(int a, int b)
{
return a + b;
}
}
Python
import ctypes
lib = ctypes.WinDLL('example.dll')
print lib.ExampleFunction(12, 34)

Creating a CPP DLL for use in a C# program

So I have a WPF solution. I added a new project and added a CPP Dll project to it.
I used this example. Pretty straight forward.
http://www.codeproject.com/Articles/9826/How-to-create-a-DLL-library-in-C-and-then-use-it-w
Here is my code
CppTestDll.cpp
#include <stdio.h>
extern "C"
{
__declspec(dllexport) void DisplayHelloFromDLL()
{
printf("Hello from DLL !\n");
}
}
When I build this I do in fact get a DLL
Now when I go into my WPF app and attempt to add a reference to this DLL I get this error.
"A reference to 'C:\DIR\testcppdll.dll' could not be added. Please
make sure that the file is accessible, and that it is a valid assembly
or COM component."
If you look in the example you cite:
Creating a simple C# application:
Start Visual Studio .NET. Go to File->New->Project.
Select Visual C#
Project. ... (you can select WPF Project)
Give the name to your application. Press OK. Into the specified
class, insert the following two lines:
[DllImport("TestLib.dll")]
public static extern void DisplayHelloFromDLL ();
In C#, keyword extern indicates that the method is implemented externally.
Your code should look something like this:
using System;
using System.Runtime.InteropServices; // DLL support
class HelloWorld
{
[DllImport("TestLib.dll")]
public static extern void DisplayHelloFromDLL ();
public void SomeFunction()
{
Console.WriteLine ("This is C# program");
DisplayHelloFromDLL ();
}
}
You don't add a reference to the to the DLL - you P/Invoke the Function using DLLImport

COM Callable Wrapper not working when called from delphi program

I've been requested to create a .Net dll for an old delphi program. I'm trying to do this with a COM Callable Wrapper, but I keep getting an error when it tries to load the dll (pretty general, something like "I couldn't load the dll"). Here is what the technical documentation says:
The DLL only needs to export one function under the name 'AUTHORIZE'.
function Authorize(InXml: PChar): PChar; stdcall;
(Delphi syntax. May be different in other languages.)
Here is my code for the CCW:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace ComCallableWrapper
{
[Guid("C3FD922A-FB44-47B1-9C0C-8F7FAF57098B")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IAuthorizer
{
[DispId(1)]
string Authorize(string lnpInXml);
}
[ProgId("ComCallableWrapper.Authorizer")]
[ClassInterface(ClassInterfaceType.None)]
public class Authorizer : IAuthorizer
{
public Authorizer()
{
}
public string Authorize(string lnpInXml)
{
return "Approved!";
}
}
}
I also run this command "regasm /tlb:ComCallableWrapper.tlb ComCallableWrapper.dll /codebase" on the computer where the delphi program is running.
I've been doing some research on google about how delphi invokes functions on a dll, and I found at least 2 ways:
function Authorize(lnpInXml: pchar): pchar; stdcall; external 'DLLName.dll';
and
oleObject := CreateOleObject('ComCallableWrapper.Authorizer');
ShowMessage(oleObject.Authorize('Approved?'));
It looks like COM works a little bit different. Is there a way to change my CCW to work like the first way?
Regards.
You con't need COM. And indeed using COM is a mistake because the Delphi program is not looking for a COM DLL.
What you need to do is to export an unmanaged function from your managed C# DLL. That's a little tricky and is in fact not supported. These are your most attractive options:
Use Robert Giesecke's UnmanagedExports.
Write a mixed mode C++/CLI DLL that consumes your C# code. The mixed mode C++/CLI is capable of export native functions using __declspec(dllexport), .def files etc.
If you chose to use UnmanagedExports, the function would look like this:
[DllExport]
public static IntPtr Authorize(string InXml)
{
// your code goes here, for now return the input value
return Marshal.StringToHGlobalAnsi(InXml);
}
Implementing the function is a little tricky because you need to return a Delphi PAnsiChar, that is a C++ char*. You cannot use string for the return type and have to use IntPtr. But how do you allocate the string so that it remains valid for the caller to use it. The code above leaks the string in an HGLOBAL.
I can't advise you definitively how to resolve the lifetime of the string. The interface you are coding to is not at all well designed. Only you with more knowledge of the interface are in a position to resolve that issue.

Compile error when calling managed C++ from C#

I am new to .net .
I have a managed C++ library. It looks like this.
// header file
namespace cppnetdll
{
public __gc class Class1
{
public:
static int foo_int(void);
};
}
// source file
namespace cppnetdll
{
int Class1::foo_int(void)
{
return 123;
}
}
I can call this from a managed c++ program. When I try to call it from
a C# program, I get the compiler error: "The type or namespace name
'Class1' could not be found (are you missing a using directive or an
assembly reference?)" The error refers to the DllImport line below.
Here is the C# code
[code:1:a72c1df571]
namespace csuser
{
public class xxx
{
[DllImport("cppnetdll.dll")] extern
int Class1.foo_int();
private void yyy() { int i =
foo_int(); }
}
}[/code:1:a72c1df571]
I have tried various approaches but no success. What is the magic
syntax ?
It's funny that I can call unmanaged C++ functions from C# fairly
easily by declaring the functions as "C" and exporting from the DLL.
I expected calling managed code to be easier. Maybe it's so easy
that no one thought of documenting it !
You do not use a [DllImport] directive to call code that's written in managed C++. That is only intended for native DLLs that export their functions. Neither of which applies to yours, it isn't native and you don't export the function.
You built a managed assembly, you can treat it just like one you'd have written in C#. Project + Add Reference, Browse tab, navigate to the DLL. Or better yet, put both projects in one solution, use the Projects tab to select the reference.
Instead of using the [DllImport ...]
Try just adding a reference, here is a how to from MSDN:
http://msdn.microsoft.com/en-us/library/7314433t%28v=VS.90%29.aspx

Export c++ functions inside a C# Application

Greetings,
I am sorry for bothering, I'll show the question:
I am trying to export some functions written in c++ in a DLL in order to import them in a C# Application running on Visual Studio.
I make the export as reported in the following code,
tobeexported.h:
namespace SOMENAMESPACE
{
class __declspec(dllexport) SOMECLASS
{
public:
SOMETYPE func(param A,char b[tot]);
};
}
tobeexported.cpp:
#include "stdafx.h"
#include "tobeexported.h"
...
using namespace SOMENAMESPACE;
SOMETYPE SOMECLASS:: func(param A,char b[tot])
{
...some stuff inside...
}
The dll is righly created and the code is already CLR-managed(looked with a disassembling software(reflector)) and contains the exported functions
then I "Add the Reference" in my c# application and the dll is found, but when
I open it with the object browser it is completely empty, neither class, nor object has been exported and ready to be used
can you help me please?
thanks
best regards
What about using managed C++ to compile your DLL? Then you just have to add a ref to the class like this:
namespace SOMENAMESPACE
{
public ref class SOMECLASS
{
public:
SOMETYPE func(param A,char b[tot]);
};
}
After successful compilation and referencing in the other project, the class should be visible. Exporting native C++ is not really portable, each compiler produces different results and is tedious to bind from within C#...
EDIT: added public access modifier to ref class...

Categories