I am developing a cross-platform wrapper for a C library in C#. This library exists in different versions, and they differ by some functions.
In the wrapper I want to enable these functions, if they are available.
For using it in C, there is a documentation on how to test for these functions:
http://jackaudio.org/api/group__WeakLinkage.html, i.e
if (jack_set_latency_callback) {
jack_set_latency_callback (jill_client, jill_latency_callback, arg);
}
My C# wrapper is defined as
[DllImport (Constants.JACK_LIB_NAME,
CallingConvention = CallingConvention.Cdecl,
EntryPoint = "jack_set_latency_callback")]
public static extern unsafe int SetLatencyCallback (UnsafeStructs.jack_client_t* client,
Callbacks.JackLatencyCallback latencyCallback,
IntPtr arg);
Now, when I call this function with older unsupported version, I get a EntryPointNotFoundException of course. How can I test, if this entry point is available?
This should not only work in Windows, but also with Mono on Linux and Mac OS X.
Call LoadLibrary to load the DLL. Then call GetProcAddress, passing the module handle returned by LoadLibrary, and the entry point name, to test whether or not the named entry point point is exported.
These two functions are documented on MSDN and a websearch will take you to this documentation. The p/invokes are easy enough to write but you may as well use the versions provided by http://pinvoke.net.
In your edit to the question you introduce Mono. Well, the answer is essentially the same, but you use dlopen and dlsym in place of LoadLibrary and GetProcAddress.
Related
I am gonna use QuantLib in C# app (http://quantlib.org/docs.shtml) but I don't trust their .NET conversion project (too immature).
I need only options valuation part.
anyone used it in managed app? whats the best approach?
What I have done in a similar situation is implementing a C++ native dll as an adapter between the C# and C++ projects.
From C# you can access your dll interface with DllImport.
In the dll you can reach the full C++ interface, but it is worth simplifying it to your exact needs on the managed site.
Example:
// in the C++ dll:
extern "C" MY_API void SetInput(double* Values, int Count);
// in C#:
[DllImport("MyStuff.dll")]
public extern static void SetInput(double[] Values, int Count);
C# wrappers for the C++ library are already available and are distributed at the QuantLib download page (these are wrappers as suggested by jmihalicza, not the ongoing C# port you're referring to in your question). The distribution also contains an example of option valuation (look under the CSharp/examples folder).
I'm trying to code the "One-minute" example of reconstructMe SDK, however their SDK is in c++ I think, I succesfully created a console application as directed on their page (here), but I want to create a simple UI, however I'm not very familiar with Visual c++ (I do know something about c++), so I tried their example for C# (I'm pretty much familiar with their UI design) but I get this error when using the C# code provided (here):
A call to PInvoke function 'Lala!Lala.Reme::reme_context_compile' has
unbalanced the stack. This is likely because the managed PInvoke
signature does not match the unmanaged target signature. Check that
the calling convention and parameters of the PInvoke signature match
the target unmanaged signature.
I think is an issue of configuring the project or something like that.
The reconstructMe DLL is using the C calling convention (Cdecl) and not the Windows calling convention (StdCall). They differ in how the stack is handled, which is why having an incorrect calling convention results in a stack imbalance.
The default for p/Invoke is StdCall, you need to manually set the CallingConvension parameter to Cdecl on the DllImport attribute:
[DllImport("example.dll", CallingConvention=CallingConvention.Cdecl)]
public static extern int function(int param);
I am trying to use SharpFFMpeg
http://sourceforge.net/projects/sharpffmpeg/
I found avcodec-52.dll and avformat-52.dll somewhere on the Net...
When I use SharpFFMpeg and make calls like av_init_packet
I get PInvoke errors like so
PInvokeStackImbalance was detected
Message: A call to PInvoke function 'WpfApplicationFFMpegTest!FFmpegSharp.Interop.FFmpeg::av_init_packet' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.
In a nutshell I am trying to decode H264 and display the incoming stream from a camera...
Just wondering if anyone has been able to do this succesfully in C#?
Thanks
What Benjamin wants to say is that you should try to open the SharpFFmpeg sources and change inside AVFormat.cs the lines
[DllImport("avformat.dll"), SuppressUnmanagedCodeSecurity]
public static extern void av_init_packet(IntPtr pAVPacket);
into
[DllImport("avformat.dll", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
public static extern void av_init_packet(IntPtr pAVPacket);
and recompile the SharpFFmpeg project. I didn't test that, since I haven't the DLLs.
When this helps (av_init_packet disappears in the exception message), try to add CallingConvention.Cdecl on every PInvoke method.
Sounds like invoke is trying to use the wrong calling convention. Needs to use __stdcall or __cdecl should work.
Depending on whether your OS is 64 or 32 bit, you'll need to ensure that the stack is aligned to sufficiently large byte amounts to make this work.
On my 64bit Windows 7 computer, I can only use FFMpeg libraries in 64bit applications, which ensures the stack stays aligned to 16byte increments, resolving many of those problems.
I'm not sure how to solve your particular problem, but I hope this helps.
I wrote my program in C++ and exported it as a DLL. I have a C# WPF GUI and I want to import the DLL to do the processing.
I am very new to C#. How can I use the C++ class in C#? I know I can't just use the .h file.
Because I used pointers in C++, in C# I couldn't use pointers. That's why I got confused. Like in C++ i used char* instead of string, and I need to return double* for a big collection of double data, and things like that.
There are a number of ways:
Export the DLL functions and use DllImportAttribute to P/Invoke into the DLL.
If it is a COM DLL, then you can generate a Runtime Callable Wrapper via TLBIMP.exe
You can use C++/CLI to build create a .Net assembly which loads and calls methods on the DLL natively.
To address your additional concerns, yes, you can use pointers in C#. If you have a function which has a double* parameter, you can declare that in C# like this:
[DllImport("Your.DLL")]
private static extern unsafe void DoProcessing(double* data, int dataSize);
You need to make sure you check the "Allow Unsafe Code" checkbox on the build tab of the C# project, and after that, you can use pointers to your heart's content.
However, note that while I'm providing the pointer signature here, since you are obviously comfortable with pointers, there are other signatures which could be more safe for you to use, and would not require you to compile C# with unsafe code. The standard marshaller in the CLR will take care of the conversion from a pointer to a C# array, provided you give it a bit of a hint if the length is required:
[DllImport("Your.DLL")]
private static extern void DoProcessing(
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] double[] data,
int dataSize);
This instructs the marshaller to use the parameter at index 1 (the 2nd parameter) as the size of the array of doubles pointed at by the 1st parameter. This allows you to avoid pointers in C#, and use safe CLI types. However, if you like pointers, my advice is to just use them - the C# will be easier for you than having to figure out how to write the method signature without them.
For more details on P/Invoke, refer to this documentation: http://msdn.microsoft.com/en-us/library/aa288468(VS.71).aspx
A lot depends on the structure of your C++ dll. If you have just a handful of functions, and they are not member functions of a class, then you can make them "extern C" functions and use the P/Invoke capability in .NET (sometimes called DllImport because of the attribute you use) to access the functions from C#.
I have win32 DLL named VssSdkd.dll. It contains two classes with names VssSdkServiceLogin and VssSdkMsg.
I need to import the VssDskServiceLogin class, in C#. I am setting few properties of VssDskServiceLogin object and passing this to VssSdkMsg which in turn invokes some other method.
How can I achieve this using C#.
I have win32 DLL named VssSdkd.dll. It
contains two classes with names
VssSdkServiceLogin and VssSdkMsg.
In C#, I need to import the
VssDskServiceLogin class. In the class
are some attributes I need to set the
value for, sending the information to
VssSdkMsg and call another function
I need to achieve those things through
C# code. Is this possible, and if so,
how?
Classes compiled in C++ (and other Win32 languages) cannot be interoped with Dot NET languages. Structures may be if care is taken. Dot NET does have support for COM objects, though.
Native functions may be called from Dot NET languages if they're tagged with the [DllImport] attribute on the CLR side (and the appropriate DllImportAttribute properties are set) - and exported on the Win32 side. However, this is a non-trivial process. I would recommend grabbing a good book on the subject and starting from the top. SO is probably not a very good medium for addressing this issue.
You can do it with p/invoke and marshaling. Read about it, it's too complicated a subject to explain fully in a SO answer.
I believe it is sometimes possible in C# through P/Invoke, but when dealing with classes, this can get very, very difficult.
I'd highly recommend creating a C# wrapper for your DLL using Managed C++ instead.
I don't know that this link will solve your problem directly, but I expect you can find a good example of how to do this at Code Project. Managed C++ can be a little tricky until you get used to it, and I think the syntax changed from .NET 1.0/1.1 to .NET 2.0. Make sure you know what version of .NET you're targeting and search the Code Project site accordingly.
Possibly what you are looking for is interoperability with COM.
I haven't worked much on it, but can give you a sample code to start with.
[DllImport("user32.dll")]
private static extern int MessageBox(IntPtr hWnd, String
text, String caption, uint type);
static void Main(string[] args)
{
MessageBox(new IntPtr(0), "Hello, world!", "My box", 0);
}
This may be of help.