I need to use a DLL created in C in a C # application. I have followed several ways seen on the internet and I can not use the methods that are supposed to be in the DLL.
When looking for the entrypoints I get 4, which are the following.
DllCanUnloadNow
llGetClassObject
DllRegisterServer
DllUnregisterServer
I'm trying with the following code:
[DllImport("DLL.dll", EntryPoint ="DllCanUnloadNow" ,CharSet = CharSet.Auto)]
public static extern int Open();
static void Main(string[] args)
{
Console.WriteLine(Open());
Console.ReadLine();
}
It doesn't matter what function I use, it returns always 0.
If I use a function called for example, asdf() I got 0.
Does anyone know how to use the DLL correctly? I think it's made as COM and I have a .lib file.
Thanks in advance.
Related
I am working on my own scripting language using C# and ANTLR, and I've been able to implement almost everything I wanted.
I know that one can't make a perfect language on themselves, so I wanna build in a way to import functions from C# scripts. For that, i've researched about DLLImport anc calling functions from that, but i just cant seem to get that to work.
I am currently stuck at an EntryPointNotFoundException, however, my system uses object instead of strictly defined types, which threw a PInvoke: cannot return variants exception.
Here's some code i tried:
Program.cs
[DLLImport("mydll.dll", EntryPoint = "main", Charset = Charset.Unicode)]
static extern object main(object[] args)
main(Array.empty<object>())
C# class library used for creatng the dll
public class Test
{
public static object main(object[] args)
{
Console.WriteLine("Test sucessful!");
return 0;
}
}
Be forgiving if i am just overthinking this or don't know something obvious, I am still a pretty inexperienced developer.
For everyone who tries to acheive the same thing, here is the solution based on #PMF's comment:
var asm = Assembly.LoadFrom("YourDLL.dll");
var type = asm.GetType("YourNamespace.YourClass");
var method = type.GetMethod("YourMethod");
object[] args = new object[0];
method.Invoke(Activator.CreateInstance(type, Array.Empty<object>()), args);
What should the syntax be to call the MacOS' os_log from C# in a .NET Core console app?
Based on
https://developer.apple.com/documentation/os/os_log
and
How to use iOS OSLog with Xamarin?
and
https://opensource.apple.com/source/xnu/xnu-4903.221.2/libkern/os/log.h.auto.html
I was expecting something like this:
using System.Runtime.InteropServices;
namespace Foo
{
class Program
{
[DllImport("__Internal", EntryPoint = "os_log_create")]
private static extern IntPtr os_log_create(string subsystem, string category);
[DllImport("__Internal", EntryPoint = "os_log")]
private static extern void os_log(IntPtr log, string format, string message);
static void Main(string[] args)
{
IntPtr log = os_log_create("some.bundle.id", "SomeCategory");
os_log(log, "%s", "Test!");
}
}
}
However, when I try to run this on my Mac I get a System.DllNotFoundException that says Unable to load shared library '__Internal' or one of its dependencies... .
Any help with this issue or P/Invoke between C# and MacOS would be very helpful, thanks!
Macro os_log
In contrast to the os_log_create function, os_log is a macro, as already mentioned in the comments.
So if you would write in C:
os_log(log, "%{public}s", "Test!");
It would finally call a function named _os_log_impl, but the first parameter of that would be a pointer __dso_handle to which we don't have access from the managed side.
Possible Solution
But you don't have to do without the new logging system from Apple. One possibility is to create a dynamic library that provides a defined API that can easily be called from the managed C# code.
How to Create a Dynamic Library in Xcode
It is easy to create a dynamic library in Xcode:
choose in XCode <File/New Project>
choose Library template in the macOS section
use Type Dynamic
Minimal Example
A minimal .c example for our own Logging library might look like this:
#include <os/log.h>
extern void Log(os_log_t log, char *message) {
os_log(log, "%{public}s", message);
}
Calling from .Net
I took your source and only slightly modified it:
using System;
using System.Runtime.InteropServices;
namespace Foo
{
class Program
{
[DllImport("System", EntryPoint = "os_log_create")]
private static extern IntPtr os_log_create(string subsystem, string category);
[DllImport("Logging", EntryPoint = "Log")]
private static extern void Log(IntPtr log, string msg);
static void Main(string[] args)
{
IntPtr log = os_log_create("some.bundle.id", "SomeCategory");
Log(log, "Test!");
}
}
}
The dynamic library created with Xcode has the name Logging. Our in C created logging function is named Log here.
Of course you can design the API as comfortable as you want, this should be a minimal example that is as close to the question as possible.
Output in Console Utility
The output in the Console utility (if you filter for some.bundle.id) would look like this:
I have one project which capture images from multiple cameras which is in C++ .I want to use that project in my new project which is in C#.I had made dll of that project.My question is ,how can i use that dll in my project.I know by passing window handle to C++ dll we can use it but i dont know how to do it and what changes should i make in dll.
Please forgive ,if it is foolish question.
I had the exact problem as you and this article helped me.
http://blogs.msdn.com/b/jonathanswift/archive/2006/10/03/dynamically-calling-an-unmanaged-dll-from-.net-_2800_c_23002900_.aspx
To pass the handle, you can add another function in C++ end. Something like,
(in the header)
extern "C" __declspec(dllexport) void SetParent(HWND hWnd);
To use the SetParent in C#
class Program
{
...
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate void SetParent(IntPtr hWnd);
public void testMethod()
{
...
IntPtr getAddress = NativeMethods.GetProcAddress(pDll, "SetParent");
...
SetParent setParent = (SetParent)Marshal.GetDelegateForFunctionPointer(getAddress, typeof(SetParent));
setParent(this.Handle);
...
}
}
If your C++ project is already in a DLL you can call any functions that it exports using P/Invoke. You will have to declare the method in your C# assembly as shown below, but then you can call it like a standard static method.
[DllImport("YourDllsName.dll")]
public static extern bool FunctionThatAWindowHandleAndReturnsBool(IntPtr hWnd);
Depending on the types of parameters that your C++ DLL's functions take the marshaling of the .Net datatypes to C data types can get complicated.
I am trying a simple program to access a C function through a dll into a C# program,
class DllImportTest
{
[DllImport("TestApp.dll", EntryPoint = "main1")]
public static extern void main1();
}
class Program
{
static void Main(string[] args)
{
DllImportTest.main1() ;
}
I have seen through the code and the name of the function is the exactly right. I have also tried using Extern "C" but, it throws me an error as its .C file.
I have placed the .Dll in the C# executable folder.
Is there something that I am doing wrong here?
Found it!
I had to use Extern "C" coupled with __declspec(dllexport) . I had never used both together, Thanks guys
Hey guys and girls :) ok so i ran this project ->
http://www.helyar.net/2009/libvlc-media-player-in-c-part-2/ and it worked perfectly (he was using .net 2.0) however when i try anything above 3.5 it gives ->
Unable to load DLL ‘libvlc’: The specified module could not be found. (Exception from HRESULT: 0x8007007E)
is there any workaround someone has done that sorts this out? MANY thanks ppl :D:D:D:D
There are two things that must be done when using that example with the new 2.0.x VLC releases. First, you have to somehow add the libvlc DLL to the search path. I used a call to SetDllDirectory to do the trick. You declare it as:
static class LibVlc
{
. . .
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool SetDllDirectory(string lpPathName);
. . .
}
Then you can call this method with the root folder of the VLC installation. On my PC, I called it as follows:
LibVlc.SetDllDirectory(#"C:\Program Files (x86)\VideoLAN\VLC");
Obviously, for a program being distributed this parameter should be configurable.
Next, the VLC API's have apparently changed because none of the methods require an exception object to be passed in anymore. It looks like return values from the methods should be checked (for example, libvlc_new() returns NULL if there was an error). I haven't tried passing in the exception object by reference like he does but the calls all work fine without it (and my interfaces now match the VLC API exactly). I also specify the calling convention to use when doing interop, just to be clear to the runtime what I expect for parameter passing order and such. For example, here are my defines for libvlc_new and libvlc_release:
[DllImport("libvlc", CallingConvention=CallingConvention.Cdecl)]
public static extern IntPtr libvlc_new(int argc,
[MarshalAs(UnmanagedType.LPArray,
ArraySubType = UnmanagedType.LPStr)] string[] argv);
[DllImport("libvlc", CallingConvention=CallingConvention.Cdecl)]
public static extern void libvlc_release(IntPtr instance);
I hope this helps!
You must copy libvlc.dll to your bin/debug folder. It must be the one from your VLC installation folder (C:\program files\videolan\vlc)