编写C ++ .dll并访问它们Unity-3D

时间:2013-11-24 23:13:21

标签: c# c++ dll unity3d

我一直在用c ++编写一个基本的dll,其最终目标是访问Unity中的一些方法。我开始使用这个教程:http://docs.unity3d.com/Documentation/Manual/Plugins.html帮助我理解了这个概念但是在我在Unity中编写类并访问.dll之后,当我点击播放时它会抛出一个入口点异常错误。是的,我有一个插件文件夹,我保存我的.dll文件。

  

EntryPointNotFoundException:添加PluginImport.Start()(at   资产/测试/ PluginImport.cs:20)

这是我的.dll课程。

标题文件:

#ifndef MATHASSISTANT_ARITHMETICS_ARITHMETIC_H
#define MATHASSISTANT_ARITHMETICS_ARITHMETIC_H

namespace ma{
    extern "C"
    {
    class Arithmetic
    {
    public:
        Arithmetic();//ctor
    protected:
        virtual ~Arithmetic();//dtor
    public:

        static __declspec(dllexport) float addition(float& val_1, float& val_2);
        static __declspec(dllexport) float substraction(float& val_1, float& val_2);
        static __declspec(dllexport) float multiplication(float& val_1, float& val_2);
        static __declspec(dllexport) float division(float& val_1, float& val_2);
    };
    }
}

#endif

这是源文件:

#include "Arithmetic.h"
#include <stdexcept>

namespace ma{


    Arithmetic::Arithmetic(){
        //TODO: Initialize items here
    }
    Arithmetic::~Arithmetic(){
        //TODO: Release unused items here
    }

    //FUNCTION: adds two values
    float Arithmetic::addition(float& val_1, float& val_2){
        return val_1 + val_2;
    }
    //FUNCTION: substracts two values
    float Arithmetic::substraction(float& val_1, float& val_2){
        return val_1 - val_2;
    }
    //FUNCTION: multiplies two values
    float Arithmetic::multiplication(float& val_1, float& val_2){
        return val_1 * val_2;
    }
    //FUNCTION: divide two values
    float Arithmetic::division(float& val_1, float& val_2){
        if(val_2 == 0)
            throw new std::invalid_argument("denominator cannot be 0");
        return val_1 / val_2;
    }
}

这是我在Unity3D中创建的类:

using UnityEngine;
using System.Collections;
using System;
using System.Runtime.InteropServices;

public class PluginImport : MonoBehaviour
{
    //Lets make our calls from the Plugin
    [DllImport("Arithmetic")]
    private static extern float addition(float val_1, float val_2);
    [DllImport("Arithmetic")]
    private static extern float substraction(float val_1, float val_2);
    [DllImport("Arithmetic")]
    private static extern float multiplication(float val_1, float val_2);
    [DllImport("Arithmetic")]
    private static extern float division(float val_1, float val_2);

    void Start()
    {
        Debug.Log(addition(5, 5));
        Debug.Log(substraction(10, 5));
        Debug.Log(multiplication(2, 5));
        Debug.Log(division(10, 2));
    }
}

如果有人能帮助我找到我做错的事情,我将非常感激。提前谢谢!

2 个答案:

答案 0 :(得分:3)

您收到此错误的原因以及您发现可以使用方法的模糊名称访问它的原因是您忘记使用正确的CallingConvention正确导入C#端的每个方法。

例如,您的Addition方法应如下所示:

[DllImport("Arithmetic"), EntryPoint = "addition", CallingConvention = CallingConvention.Cdecl)]
private static extern float addition(float val_1, float val_2);

答案 1 :(得分:0)

我找到了答案。我不得不对代码进行一些调整,但基本上我会告诉你:

这是我的MathHelper.dll

标题:

#ifndef MATHASSISTANT_ARITHMETICS_ARITHMETIC_H
#define MATHASSISTANT_ARITHMETICS_ARITHMETIC_H
#include <Windows.h>

#include <WbemCli.h>  
namespace ma{
    extern "C"
    {
    class Arithmetic
    {
    public:
        Arithmetic();//ctor
    protected:
        virtual ~Arithmetic();//dtor
    public:
        BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID);
        __declspec(dllexport) float addition(float val_1, float val_2);
        __declspec(dllexport) float substraction(float val_1, float val_2);
        __declspec(dllexport) float multiplication(float val_1, float val_2);
        __declspec(dllexport) float division(float val_1, float val_2);
    };
    }
}

#endif

源文件:

#include "Arithmetic.h"
#include <stdexcept>

namespace ma{


    Arithmetic::Arithmetic(){
        //TODO: Initialize items here
    }
    Arithmetic::~Arithmetic(){
        //TODO: Release unused items here
    }

    //FUNCTION: adds two values
    __declspec(dllexport) float addition(float val_1, float val_2){
        return val_1 + val_2;
    }
    //FUNCTION: substracts two values
    __declspec(dllexport) float substraction(float val_1, float val_2){
        return val_1 - val_2;
    }
    //FUNCTION: multiplies two values
    __declspec(dllexport) float multiplication(float val_1, float val_2){
        return val_1 * val_2;
    }
    //FUNCTION: divide two values
    __declspec(dllexport) float division(float val_1, float val_2){
        if(val_2 == 0)
            throw new std::invalid_argument("denominator cannot be 0");
        return val_1 / val_2;
    }
}

在Unity-3D中,这里是班级:

using UnityEngine;
using System.Collections;
using System;
using System.Runtime.InteropServices;

public class PluginImport : MonoBehaviour
{
    //Lets make our calls from the Plugin
    [DllImport("MathAssistant", EntryPoint = "?addition@ma@@YAMMM@Z")]
    private static extern float addition(float val_1, float val_2);
    [DllImport("MathAssistant", EntryPoint = "?substraction@ma@@YAMMM@Z")]
    private static extern float substraction(float val_1, float val_2);
    [DllImport("MathAssistant", EntryPoint = "?multiplication@ma@@YAMMM@Z")]
    private static extern float multiplication(float val_1, float val_2);
    [DllImport("MathAssistant", EntryPoint = "?division@ma@@YAMMM@Z")]
    private static extern float division(float val_1, float val_2);

    void Start()
    {
        Debug.Log(addition(5, 5));
        Debug.Log(substraction(10, 5));
        Debug.Log(multiplication(2, 5));
        Debug.Log(division(10, 2));
    }
}

我之前遇到的错误是代码无法识别我的功能,添加,除法等。即使我正确地声明了它们。然而,当我创建我的.dll时,它以某种方式改变了我的功能名称,即:“添加”变为:“?add @ ma @@ YAMMM @ Z”。我去了这个网站,它明确表示:http://msdn.microsoft.com/en-us/library/system.entrypointnotfoundexception(v=vs.110).aspx这就是我意识到问题不是在我的结构或逻辑中,而是在实际的函数名称转换为.dll后。如果这是你的情况,那么你需要的是一个工具来帮助你找到你的函数名称。我使用了DependancyWalker.exe。这是网站:http://dependency-walker.en.softonic.com/这是我试图解决这个问题的小冒险。希望这将有助于任何遇到过这种情况并且还没有解决它的人。为用户提供动力!