【问题标题】:Is it possible to add C references to an objective c binding?是否可以将 C 引用添加到目标 c 绑定?
【发布时间】:2013-01-06 04:34:28
【问题描述】:

我绑定的 Objective C 库中有一些 C 风格的函数,我需要在我的应用程序中访问这些函数。是否可以以任何方式将这些添加到绑定中,以便我可以在我的 C# 应用程序中访问它们?

来自 Cocos2d 的示例:

void ccGLActiveTexture( GLenum textureEnum )
{
#if CC_ENABLE_GL_STATE_CACHE
    NSCAssert1( (textureEnum - GL_TEXTURE0) < kCCMaxActiveTexture, @"cocos2d ERROR: Increase kCCMaxActiveTexture to %d!", (textureEnum-GL_TEXTURE0) );
    if( (textureEnum - GL_TEXTURE0) != _ccCurrentActiveTexture ) {
        _ccCurrentActiveTexture = (textureEnum - GL_TEXTURE0);
        glActiveTexture( textureEnum );
    }
#else
    glActiveTexture( textureEnum );
#endif
}

编辑

链接到带有我正在尝试导入的函数的标题: http://www.cocos2d-iphone.org/api-ref/2.0.0/cc_g_l_state_cache_8h_source.html

我在我的 Extras.cs 中尝试过这个

public partial class CCGLProgram {
[DllImport("__Internal")]
    public static extern void ccGLUseProgram( uint program );

    public static void CCGLUseProgram(uint test)
    {
        ccGLUseProgram(test);
    }
}

不幸的是,我收到了一个找不到入口点的错误。我想我的第一个想法可能是函数被破坏了,但我想既然'extern C'在那里不应该发生?谁能帮帮我?

【问题讨论】:

  • 像什么?展示“Objective C 中的 C 风格函数”的示例
  • 你是指 GLenum 类型还是函数本身?
  • 您是否尝试过将您的代码编译为 DLL,并在您的 DLL 中将您想从 C# 调用的任何函数作为 EXPORT?我在这里没有得到你的确切问题。如果您只想从 C# 调用一个用 C++ 编码的函数,则必须将其编译为 DLL,进行导出并从 C# 调用导出的函数。
  • 我从这里 github.com/mono/monotouch-bindings 使用 Cocos2d 的目标 c 绑定。但是,它不包括我需要的所有功能,所以我一直在添加到 ApiDefinition。添加 Objective C 类/函数对我来说很容易,但 Cocos2d 还包括重要的 C 函数,就像您在上面看到的那样。我不知道如何将它添加到 ApiDefinition,或者是否可能。我只是好奇将它添加到绑定的最佳方法是什么,以便我可以从包含 cocos2d dll 的 C# 项目中引用上述 C 函数。 (而且我确实有一个 DLL)
  • 你的 c++ 编译器是什么?你使用任何 IDE 吗?

标签: c# objective-c c binding xamarin.ios


【解决方案1】:

您可以添加 classic .NET p/invokes[DllImport],以获取您需要的任何其他 C API。它们可以很容易地添加到您的绑定程序集中,因为绑定是一个 步骤过程。

首先将您的 API 定义(接口)与额外定义(例如 enums)一起编译到临时程序集中。

接下来使用该程序集生成代码(使用btouch):您将使用的绑定。在那个阶段可以包含更多代码,例如 p/invokes,因此它们将成为您最终编译的绑定程序集的一部分。

技巧:GIT 的monotouch-bindings 中有很多示例可用,只需搜索DllImport 即可找到一些示例。

编辑 (2013-01-08)

Makefile 完成的 Release 构建(即使它只是调用 xcodebuild)有问题,因为它在我在调试中重建 libcocos2d.a 时工作。例如

cd monotouch-bindings/cocos2d/binding
make debug

为了测试这一点,我将您的代码(有点简化)添加到现有的extra.cs

public partial class CCGLProgram {
    [DllImport ("__Internal", EntryPoint="ccGLUseProgram")]
    public static extern void UseProgram (uint program);
}

并从 Jumpy 演示应用的 FinishedLaunching 方法内部添加了对 CCGLProgram.UseProgram (0); 的调用。

编辑 (2013-01-12)

调试和发布版本非常相似(不足为奇)。 debug 构建有一些与调试相关的定义(同样不足为奇)。 OTOH release 构建是使用-fvisibility=hidden 完成的(我需要稍后验证)听起来是解决这个问题的好人选。

这确实是 Xcode 项目中的一个(非默认设置,请参见最后一列)构建设置。将此设置更改为 No(通常是默认设置)将生成 Release 构建,您可以在其中使用 normal [DllImport](如上)调用 C 函数。谜团解开了:-)

编辑 (2013-01-13)

这个change is now 在 MonoTouch 的绑定 Makefile 中处理,即重新构建您的 Cocos2d.dll 程序集(同时执行 make cleanmake clean all 以删除托管代码和本机代码)将自动解决此问题。玩得开心!

【讨论】:

  • 再次感谢 poupou。昨晚我最终发现了有关使用 DllImport 的信息,但我无法让它工作,但我不知道把它放在哪里。 (我首先尝试将它放在 Extras 中,然后再次放在我的实际 C# 项目中)我将检查示例,看看是否可以找到可以帮助我的示例。
  • 我搜索了github找不到Dllimport:repo:mono/monotouch-bindings Dllimport
  • 您在正确的轨道上,源代码方面,但可能不是构建方面。现在您需要验证 (a) 您是否将静态库正确链接到您的应用程序,例如架构不匹配,并且 (b) 符号存在于您拥有的静态库中,例如它被记录在 coco2d 2.0+ 中,所以早期版本不会有那个符号(这会给你一个例外)。
  • 我还没有比较(发布/调试)构建日志 - 但只需要一个配置错误的宏,所有东西(或单个东西)都可能被破坏.
  • 感谢您的完整回答。我希望将来如果其他人有类似的问题,这个答案可以帮助他们。我花了一段时间才回到这个问题,因为我一直很忙,但现在我可以继续我的项目了,再次感谢 Poupou!
【解决方案2】:

只是一个疯狂的猜测,你提到它适用于调试但不适用于发布。这可能是因为符号被 mtouch “剥离”了。

为了测试这一点,请在实际引用绑定项目的项目上添加 --nosymbolstrip 到发布配置并试一试。

这确实会影响应用程序的最终大小,但至少您会知道这是问题所在,我们可以制定解决方法,将在博客中发布相关内容。

如果这对你有用,请告诉我。

希望这会有所帮助。

亚历克斯

【讨论】:

  • 这是一个很好的猜测。遗憾的是,我使用的 MonoTouch 项目在这两种情况下都是 Debug (所以mtouch 从未剥离任何东西)。有效的是 cocos2d.a debug 构建(来自 xcode),而 release 构建缺少一些符号。我可能与 MT 相关(想不出如​​何),但在 xcode 构建中肯定有一些不同的东西(正确与否 - 但不同)。
  • 啊,所以它在 xcode 端,该项目在 Git 上可用吗?我的意思是你们正在使用的最新的 Cocos2d xcode 项目??
  • Makefile 下载(解压缩和构建)2.0 的源代码包
猜你喜欢
  • 2020-01-17
  • 2015-10-17
  • 1970-01-01
  • 1970-01-01
  • 2013-01-02
  • 2021-04-17
  • 2021-10-24
  • 1970-01-01
  • 2013-11-13
相关资源
最近更新 更多