How do I call method C# Dll method using RegAsm? - c#

I created a C# Dll that use "Register for com interop" and I managed to register it using RegAsm:
RegAsm.exe -tlb -codebase MathLib.dll
After that I got the message:
"Assembly exported to 'C:\Test\MathLib.tlb', and the type library was registered successfully"
How do I call now the methods inside the Dll? For example it has a public function:
int Add(int a, int b) { return a + b; }
that adds 2 numbers and return the result. How do I call it from the command-line and see the result of the operation?
Thanks very much.

How does it work?
Create a new classlibrary or proceed with an
existing one. Then add the UnmanagedExports Nuget package.
This is pretty much all setup that is required.
Now you can write any kind of static method, decorate it with
[DllExport] and use it from native code. It works just like DllImport,
so you can customize the marshalling of parameters/result with
MarshalAsAttribute.
During compilation, my task will modify the IL to add the required
exports.
A good example would be the following lines:
class Test
{
[DllExport("Add", CallingConvention = CallingConvention.Cdecl)]
public static int Add(int a, int b)
{
return a + b;
}
}
As you know, keep registering your lib with RegAsm. To import your COM function back on another project, you shall Marshall it like a native method, declaring it in your code with the [DLLImport] attribute.
References:
Unmanaged Exports
UnmanagedExports Nuget package
I hope that helped in someway.

Related

how to get dependency of my C# dll in ctypes library python?

I want to run C# dll with .net framework 4.7 in python app.
I use dllExport nuget for my method in dll because ctypes with this way access my method.
Sample:
using System.Runtime.InteropServices;
namespace MyNameSpace
{
public class MyClass
{
[DllExport("MyMethod", CallingConvention = CallingConvention.StdCall)]
public static int MyMethod(int a,int b)
{
return a + b;
}
}
}
In python:
def myFunction():
Dllpath = os.path.join("dll folder directory")
os.add_dll_directory(Dllpath + r"myDll.dll")
# WinDll used just windows os, in Linux is different
lib = WinDLL(Dllpath + r"myDll.dll")
lib.MyMethod(12,17)
it is work.
but when I use other library (dll) in my dll I get this Error:
[WinError -532462766] Windows Error 0xe0434352
I guess this error was for problem in dependency of my dll.
how to resolve this error?
you should put "DllExport" above all functions you call in all dependencies too.

How can I create and use a dynamic library ".so" from CUDA C++ and use it inside C# code under Linux environment (CentOS)?

I am trying to create a dynamic library .so using CUDA C++ kernel to use it inside C# code under Linux environment (CentOS). I searched for a way yo do this, but unfortunately didn't find a complete clear solution for it. Some solutions only make partial part of it, like creating C++ shared library on Linux, or creating chain of libraries in CUDA using nvcc, but there was no method for creating a dynamic library from CUDA C++. The using of .so created from C++ seamed possible like in this solution.
Is there a way to create this dynamic library and use it successfully inside C# code?
After searching multiple different solutions, and trying to collect and test the available possibilities, I finally reached to this simple method.
The original C++ library can be made using gcc in one step like this answer.
gcc -shared -o dll.so -fPIC dllmain.cpp
but make sure to add extern "C" before the required function(s) inside .cpp file, like this:
#include <stdio.h>
extern "C" void func()
{
// code
}
For CUDA C++, nvcc can be used in the same way similarly to this answer and this answer combined. Make sure to use .so instead of .dll and use the proper device architecture, I used 60 here as I am using "Tesla P100-PCIE-16GB".
nvcc -arch=sm_60 --compiler-options '-fPIC' -o dll.so --shared kernel.cu
The .cu file will be similar to this.
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
extern "C" void myfunc(int a, int b, ...);
__global__ void kernel(int a, int b, ...);
__global__ void kernel(int a, int b, ...)
{
int i = threadIdx.x;
// kernel code
}
void myfunc(int a, int b, ...)
{
// code
}
Now the dynamic library .so is created and can be used inside C# code like this.
using System;
using System.Runtime.InteropServices;
class Program
{
[DllImport("dll.so")]
static extern myfunc(int a, int b, ...);
private void Method()
{
int a, b;
// code
myfunc(a, b, ...);
}
}
The C# code then is compiled using Mono.
mcs Program.cs
mono Program.exe
But it will probably be necessary to set the path of the used library like this.
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/library/
This worked for a simple CUDA C++ code, it will likely work for other ones, but some problems may arise depending on their complexity.

Call a function in a console app from VBScript

I have a console app, myapp.exe. Within the app is a function, let's call it:
public static int AddIntegers(int a, int b)
Is it possible to make this function visible externally so that a VBscript could call it? Do I have to move the function into a DLL or can I leave it in the EXE and make it visible? If so, how?
Idealistically, you should be making a DLL and set Com Visible on the functions you need to expose.
using System;
using System.Runtime.InteropServices;
namespace MyDLL
{
[ComVisible(true)]
public class Operations
{
[ComVisible(true)]
public int AddIntegers(int a, int b)
{
return a + b;
}
}
}
After you've compiled your DLL you need to register it with regasm.exe so that you can call it from VBScript:
Dim myObj
Set myObj = CreateObject("MyDLL.Operations")
Dim sum
sum = myObj.AddIntegers(3, 5)
This reply is based on the CodeProject posting How to call a .NET DLL from a VBScript by Raymund Macaalay. I recommend you read it.
Also, you should check other stackoverflow posting such as How to call C# DLL function from VBScript.
Yes, you will need to make the managed code library (DLL) visible to the VBScript (most likely through the GAC). Then in your VBScript, you can do something like:
dim yourObject = CreateObject("YourContainingObject");
yourObject.AddIntegers yourFirstInt, yourSecondInt

BadImageFormatException error when using C++ .dll function for C#?

I am having trouble with using P/Invoke for C#. Here is the function (written in C++) that I am trying to call from the .dll:
string
BeatTracker::getName() const
{
return "Tempo and Beat Tracker";
}
And here is my code for trying to call this function:
[DllImport("qm-vamp-plugins.dll",EntryPoint="BeatTracker")]
public static extern string getName();
public QMTempo()
{
Console.WriteLine(getName());
}
What seems to be wrong? I am getting a BadImageFormatException. And how can I know what is wrong in future references aside from the vague names the IDE is giving me? I am using Visual Studio 2008 by the way.
Also I am using (but not sure if right) EntryPoint, to let it know that I am using the getName function from the BeatTracker class (because there are also getName functions for other classes, which are included in the single .dll file)
Thanks!
This exception can be caused by a mismath between the .NET runtime proc architecture used and the imported dll one.
More precisely:
Do you use a 64bit Windows? The runtime will, by default, run in 64bit. If your C++ library was compiled targeting 32bit, you will get a BadFormatException upon library loading. The Same goes if your .NET app is running 32bit and your C++ library was compiled targeting x64.
If you can recompile the library, do it. Otherwise you can force the .NET runtime to use a specified architecture at compilation, but it will prevent it from running on the other architecture. It's your choice ;) When coding against .NET or java, we tend to forget what really happen under the hood.
[DllImport("qm-vamp-plugins.dll",EntryPoint="BeatTracker")]
The EntryPoint should be getName(), not BeatTracker which is a class!
But even then you cannot call that, because getName() is member function which cannot be callled without instance.
So I would suggest that define free functions in the DLL, and export them. You can use class internally, in the DLL. You can work with handle of classes.
Example,
DLL code:
typedef BeatTracker* PBeatTracker;
typedef PBeatTracker HBeatTracker;
//exported functions
HBeatTracker CreateBeatTracker()
{
return new BeatTracker();
}
void DeleteBeatTracker(HBeatTracker handle)
{
delete handle;
}
string getName(HBeatTracker handle)
{
return handle->getName();
}
C# Code:
[DllImport("qm-vamp-plugins.dll",EntryPoint="CreateBeatTracker")]
public static extern IntPtr CreateBeatTracker();
[DllImport("qm-vamp-plugins.dll",EntryPoint="DeleteBeatTracker")]
public static extern void DeleteBeatTracker(IntPtr);
[DllImport("qm-vamp-plugins.dll",EntryPoint="getName")]
public static extern string getName(IntPtr);
public QMTempo()
{
IntPtr handle = CreateBeatTracker();
Console.WriteLine(getName(handle));
DeleteBeatTracker(handle);
}

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

Categories