简体   繁体   English

从C#调用纯C函数时,首先是DllNotFoundException然后是EntryPointNotFoundException

[英]First DllNotFoundException then EntryPointNotFoundException while calling pure C function from C#

I am trying to use some C code in Unity3D pro. 我想在Unity3D pro中使用一些C代码。

My basic approach is to (1) build C source code into a static libary (2) create an empty bundle and link against the library (3) import the bundle into Unity 3D pro (as a plugin). 我的基本方法是(1)将C源代码构建到静态库中(2)创建一个空包并链接到库(3)将包导入Unity 3D pro(作为插件)。

I was basically following this tutorial . 我基本上是按照本教程

It has been working for me for a while until recently when I was updating my C code and recompiling and rebuilding the library and the bundle, everything goes wrong... 它一直在为我工作一段时间,直到最近我更新我的C代码并重新编译和重建库和捆绑包,一切都出错了......

When I first imported the bundle, I got a DllNotFoundException . 当我第一次导入捆绑包时,我得到了一个DllNotFoundException

At that stage my bundle project was merely a pile of libraries - the library built from my source code (which is a .a file) and a few other libraries that I think the .a library depends on (the other libraries have .dylib extension). 在那个阶段,我的bundle项目只是一堆库 - 从我的源代码(一个.a文件)构建的库和我认为.a库所依赖的一些其他库(其他库具有.dylib扩展名) )。

I added one test.c file to the bundle. 我在bundle中添加了一个test.c文件。 The test .c file contains only two lines: 测试.c文件只包含两行:

#include <stdio.h>
#include "ccn.h"

char* say()
{
    return "hi";
}

in which ccn.h is a header file from my C source code. 其中ccn.h是我的C源代码中的头文件。

After I re-built the bundle, the DllNotFoundExeption was gone, but I got an EntryPointNotFoundException . 在我重新构建捆绑包之后, DllNotFoundExeption消失了,但我得到了一个EntryPointNotFoundException

Here is what I am thinking: 这就是我的想法:

  1. Because Xcode is so intelligent, I am guessing that while was adding the simple test.c file, Xcode modified some of my bundle settings for me. 因为Xcode非常聪明,我猜测在添加简单的test.c文件时,Xcode为我修改了一些我的包设置。 And I believe that's the reason why DllNotFoundException is gone in the first place. 我相信这就是为什么DllNotFoundException首先消失的原因。 Am I thinking right? 我在想吗?
  2. I think to solve the EntryPointNotFound problem I will also have to modify some bundle project setting - but I don't know how... Please help me... 我想要解决EntryPointNotFound问题我还要修改一些捆绑项目设置 - 但我不知道怎么...请帮帮我...

Lots and Lots of thanks! 很多和很多的感谢!

Edit 编辑

  1. I saw this thread suggesting that since Xcode is using g++ to compile, I will need extern "C" even if my unmanaged code is in pure C. I changed my target setting in Xcode4 for " Compiler for C/C++/Objective-C " from Apple LLVM 3.0 to LLVM GCC 4.2 , but I still get the same exception. 我看到这个帖子暗示,由于Xcode使用g ++进行编译,即使我的非托管代码是纯C,我也需要extern“C”。我在Xcode4中更改了我的目标设置“ Compiler for C / C ++ / Objective-C ”从Apple LLVM 3.0LLVM GCC 4.2 ,但我仍然得到相同的例外。
  2. I also saw this mono documentation that says mono is using GLib to load libraries, and Glib has a bug on Mac OS X which is that it doesn't recognize .dylib libraries. 我还看到这个单声道文档说单声道使用GLib加载库,而Glib在Mac OS X上有一个错误,它无法识别.dylib库。 I deleted the .dylib libraries and tried again but I was till getting the same exception. 我删除了.dylib库并再次尝试,但直到得到相同的异常。
  3. Also Apple's documentation says that every loadable bundle must have a principal class, and if user doesn't specify which class is the principal class, NSBundle will use the first class shown in the Xcode project as the principal class. 此外, Apple的文档说每个可加载的包必须有一个主类,如果用户没有指定哪个类是主类,NSBundle将使用Xcode项目中显示的第一个类作为主类。 Well, I guess the bundle that I created is a loadable bundle, but because it's merely a static library built from C, it literally doesn't have any class. 好吧,我想我创建的包是一个可加载的包,但因为它只是一个用C构建的静态库,所以它实际上没有任何类。 When I looked at my project's info.plist , the Principal Class entry is just empty. 当我查看我的项目的info.plist时Principal Class条目只是空的。 Could this be the problem? 这可能是问题吗? If so, how do I solve it? 如果是这样,我该如何解决?
  4. Also I saw something on Apple's documentation that I don't quite understand: 另外我在Apple的文档中看到了一些我不太明白的东西:

    If your loadable bundle is a plug-in, the host application developer usually provides an interface for the plug-in architecture in a framework. 如果可加载包是一个插件,则主机应用程序开发人员通常在框架中为插件体系结构提供接口。 This framework typically contains a class that all plug-in principal classes inherit from, or a protocol (formal or informal) for the plug-in's principal class to adopt. 此框架通常包含所有插件主体类继承的类,或者插件的主体类要采用的协议(正式或非正式)。

    I am pretty sure the loadable bundle I create is a plugin. 我很确定我创建的可加载包是一个插件。 I am importing the bundle into Unity3D. 我正在将捆绑包导入Unity3D。 Does that mean I should define a principal class from Unity? 这是否意味着我应该从Unity定义一个主要类? How? 怎么样?

The problem has a simple solution: 问题有一个简单的解决方案:

try out whatever function that is giving you the EntryPointNotFoundException in the test.c file first. 尝试先在test.c文件中为您提供EntryPointNotFoundException的任何函数。

By "try out" I mean, have the function called in your main() and test it out in C first. 通过“试用”我的意思是,在main()中调用函数并首先在C中测试它。

In my case, the function that throws out the EntryPointNotFoundException is called ccn_run(). 在我的例子中,抛出EntryPointNotFoundException的函数称为ccn_run()。 So I did the following things: 所以我做了以下事情:

  1. add a main() function to test.c 在test.c中添加一个main()函数
  2. type ccn_run() in the main() function 在main()函数中键入ccn_run()
  3. add a command line target in Xcode project and test it out 在Xcode项目中添加一个命令行目标并测试它

I tried it out and the function is working alright in C, now the magical thing is that when I rebuild the bundle (without deleting the main() function and the ccn_run() call inside it), Unity can call the ccn_run() function without problem! 我试了一下,函数在C中工作正常,现在神奇的是当我重建bundle时(不删除main()函数和ccn_run()调用),Unity可以调用ccn_run()函数没有问题!

I couldn't explain why this solves my problem, but this has been working for me for almost a month now. 我无法解释为什么这可以解决我的问题,但这已经为我工作了近一个月了。 Not long ago Xcode upgraded to 4.3.2 and I tried the same approach again, still works. 不久前Xcode升级到4.3.2并且我再次尝试了相同的方法,仍然有效。 I guess perhaps adding a main() function helps defining the entry point? 我想也许添加一个main()函数有助于定义入口点?

Finally, I documented the whole process of importing C code to Unity and I am glad to share here: https://docs.google.com/document/d/1vAeupNQlBTY3y3Bma5Jo_Hs4JRYm6FoEc4vQN0WBGNg/edit 最后,我记录了将C代码导入Unity的整个过程,我很高兴在此分享: https//docs.google.com/document/d/1vAeupNQlBTY3y3Bma5Jo_Hs4JRYm6FoEc4vQN0WBGNg/edit

My code sample: 我的代码示例:

  1. Xcode project: https://github.com/CherryQu921/CCNxPlugin Xcode项目: https//github.com/CherryQu921/CCNxPlugin
  2. Unity project: https://github.com/CherryQu921/cqs Unity项目: https//github.com/CherryQu921/cqs

Hope this answer especially my tutorial helps! 希望这个答案特别是我的教程帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM