3

I have a trouble invoking C function from my C# code. I wanted to add some functionality to VLC player(we use it in our software through vlcdotnet) and cross-compiled it on my ubuntu 12.10 for windows using mingw. I wrote a function, let's call it Foo:

__declspec(dllexport) void Foo(vlc_object_t* bar);

Now I want to call it from C#:

[LibVlcFunction("Foo")]
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void Foo(IntPtr pointer);
........
public LibVlcFunction<Foo> Foo { get; private set; }
......
Foo = new LibVlcFunction<Foo>(myLibVlcCoreDllHandle, VlcVersion);

And it fails. Inside constructor of LibVlcFunction we have combination of GetProcAddress and GetDelegateForFunctionPointer. GetProcAddress fails with "The address of function 'Foo' doesn't exists...." but dumpbin and dep. walker are saying that function exists and her name is not mangled. I tried to write a C++ app that loads a libvlc.dll and gets pointer to my func and it worked. But in C# it fails. What should I do? Any suggestions?

  • 1
    Might it be possible to use DllImport and an Extern on the C# side? I've never personally worked with VLC from a coding standpoint so I don't know if there's a reason you must use the attributes you're using here, it's just a thought. – Leon Newswanger Jan 31 '13 at 14:12
  • DllImport works only if Dll is placed in the same folder as an application. We need them in separate folders, so we use GetProcAddress/GetDelegateForFunctionPointer combination. –  Jan 31 '13 at 14:15
  • Got it, sorry it was just my initial thought due to personal experience. – Leon Newswanger Jan 31 '13 at 14:23
  • " I tried to write a C++ app that loads a libvlc.dll and gets pointer to my func and it worked" ... Did you use GetProcAddress in the C++ program also? Can you double-check that both the C++ program and the C# one refer to the same file? – dsign Jan 31 '13 at 14:24
  • 4
    You can easily make [DllImport] work with DLLs in non-standard directories. Getting help with this contraption you came up with is going to be difficult, nobody can see your code from here. – Hans Passant Jan 31 '13 at 14:27
  • Yep, I used GetProcAddress in Cpp too. Double-checked. Both versions refer to libvlc.dll that is one and only on my PC. –  Jan 31 '13 at 14:28
  • possible duplicate of [Change C# DllImport target code depending on x64/x86](http://stackoverflow.com/questions/11934570/change-c-sharp-dllimport-target-code-depending-on-x64-x86) – Hans Passant Jan 31 '13 at 14:29
  • "You can easily make [DllImport] work with DLLs in non-standard directories." Didn't know that. Thanks, I'll try this approach. –  Jan 31 '13 at 14:32
  • Unless you post the code how do you expect us to help you? The method signatures are not enough. – Security Hound Jan 31 '13 at 17:43
  • What about Mono runtime? – Arunkumar Chandrasekaran Feb 21 '13 at 06:11

1 Answers1

0

Try not using stdcall and, instead, use cdecl, like this:

 extern "C" __declspec(dllexport) void Foo(vlc_object_t* bar);

Your platform invoke call, would like this:

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;

public class libvlc
{
    [DllImport("the-vlc.dll", EntryPoint = "Foo")]
    extern public static void Foo( IntPtr bar );
}

You will treat vlc_object_t* as opaque handles. You just pass them around. This assumes that vlc_object_t's are allocated and freed in your VLC shared library (i.e. in the DLL).

Man Vs Code
  • 1,058
  • 10
  • 14