【问题标题】:Problems with C and C# interopC 和 C# 互操作的问题
【发布时间】:2013-01-15 15:39:27
【问题描述】:

我无法从我的 C# 代码中调用 C 函数。我想为 VLC 播放器添加一些功能(我们通过 vlcdotnet 在我们的软件中使用它)并使用 mingw 在我的 ubuntu 12.10 for windows 上交叉编译它。我写了一个函数,我们称之为 Foo:

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

现在我想从 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);

它失败了。在 LibVlcFunction 的构造函数中,我们结合了 GetProcAddress 和 GetDelegateForFunctionPointer。 GetProcAddress 因“函数 'Foo' 的地址不存在......”而失败,但 dumpbin 和 dep。沃克说功能存在,她的名字没有被破坏。我试图编写一个加载 libvlc.dll 并获取指向我的函数的指针的 C++ 应用程序,它可以工作。但在 C# 中它失败了。我该怎么办?有什么建议吗?

【问题讨论】:

  • 是否可以在 C# 端使用 DllImport 和 Extern?从编码的角度来看,我从来没有亲自使用过 VLC,所以我不知道你是否有理由必须使用你在这里使用的属性,这只是一个想法。
  • DllImport 仅在 Dll 与应用程序放置在同一文件夹中时才有效。我们需要将它们放在单独的文件夹中,因此我们使用 GetProcAddress/GetDelegateForFunctionPointer 组合。
  • 知道了,很抱歉,由于个人经验,这只是我最初的想法。
  • “我试图编写一个 C++ 应用程序,它加载一个 libvlc.dll 并获取指向我的 func 的指针并且它工作”......你在 C++ 程序中也使用了 GetProcAddress 吗?您能否再次检查 C++ 程序和 C# 程序是否引用同一个文件?
  • 您可以轻松地使 [DllImport] 与非标准目录中的 DLL 一起工作。获得有关您想出的这个装置的帮助将很困难,没有人可以从这里看到您的代码。

标签: c# c dll interop mingw


【解决方案1】:

尽量不要使用 stdcall,而是使用 cdecl,如下所示:

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

您的平台调用调用是这样的:

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 );
}

您将 vlc_object_t* 视为不透明句柄。你只是传递它们。这假定 vlc_object_t 已在您的 VLC 共享库(即 DLL 中)中分配和释放。

【讨论】:

    猜你喜欢
    • 2017-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多