【问题标题】:Writing C++ .dlls and access them Unity-3D编写 C++ .dll 并访问它们 Unity-3D
【发布时间】:2013-11-24 23:13:21
【问题描述】:

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

EntryPointNotFoundException: 添加 PluginImport.Start() (在 Assets/Test/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));
    }
}

如果有人能帮助我找出我做错了什么,我将不胜感激。提前致谢!

【问题讨论】:

标签: c# c++ dll unity3d


【解决方案1】:

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

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

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

【讨论】:

  • 是的,它也做到了!谢谢你:)
  • 为什么我必须为类函数使用经过混淆的方法名称? “好看”的函数名称不起作用并给我同样的错误?
【解决方案2】:

我找到了答案。我必须对代码进行一些调整,但基本上我会向您展示:

这是我的 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 时,它以某种方式更改了我的函数的名称,即:“addition”变为:“?addition@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/ 那是我试图解决这个问题的小冒险。希望这将帮助任何遇到此问题但尚未解决的人。给用户权力!

【讨论】:

  • 看我的回答。您不需要使用经过混淆的方法名称。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-07
  • 1970-01-01
  • 2020-02-02
相关资源
最近更新 更多