How should I call my C++ function from Unity3D

This is a little bit difficult because I don't even know if my C++ is well implemented.

I want to call a function from Unity3D which I pass some parameters such float *points and my C++ writes in that pointer.

Well, starting from the C++ part, I've written:

main_function.cpp this is my main function in C++ which works perfectly as binary, for example.

#include "main_function.h"

extern "C" void getPoints (uchar *data, float *points, int rows, int cols, const char *trackername) {
    //load detector model
    face_tracker tracker = load_ft<face_tracker>(trackername);

    //create tracker parameters
    face_tracker_params p; p.robust = false;
    p.ssize.resize(3);
    p.ssize[0] = Size(21,21);
    p.ssize[1] = Size(11,11);
    p.ssize[2] = Size(5,5);

    Mat im = Mat(Size(cols, rows), CV_8U, data);

    if(tracker.track(im,p))
        tracker.draw(im, points);

}

main_function.h

#include "opencv_hotshots/ft/ft.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>

extern "C" {
    void getPoints (uchar *data, float *points, int rows, int cols, const char *trackername);
}

Then I want to wrap my C++ code to C#, so I make the:

AEDwrapper.h

// AEDwrapper.h
#pragma once

#ifdef TESTFUNCDLL_EXPORT
#define TESTFUNCDLL_API __declspec(dllexport) 
#else
#define TESTFUNCDLL_API __declspec(dllimport) 
#endif

using namespace System;
#include "stdafx.h"
#include "C:UsersRafaelDesktopAEDlibrarymain_function.h"
extern "C" {
    namespace AEDwrapper {

        TESTFUNCDLL_API public ref class AED
        {
            void getPointsAED (uchar *data, float *points, int rows, int cols, const char *trackername);
        };
    }
}

and AEDwrapper.cpp

// Archivo DLL principal.    
#include "stdafx.h"
#include <ctime>
#include <iostream>
#include <chrono>
#include <sys/timeb.h>

#include "AEDwrapper.h"

using namespace std::chrono;

extern "C" {
    void AEDwrapper::AED::getPointsAED (uchar *data, float *points, int rows, int cols, const char *trackername){
        getPoints(data, points, rows, cols, trackername);
    }
}

I build it and it becomes in a AEDwrapper.dll .

Now in Unity3D, in the C# part (script) I try to do:

[DllImport ("/Assets/plugins/AEDwrapper.dll")]   
// or [DllImport ("AEDwrapper")]
private static extern unsafe void getPointsAED (byte* data, float* points, int rows, int cols, sbyte* trackername); 
//DECLARA METODO DEL DLL

DllNotFoundException: /Assets/plugins/AEDwrapper.dll

I know I could be wrong in early steps from my code, but have you ever done that before??? I'm kind of lost.

Thank you in advance.

Rafael.


EDIT:

I've tried with a simple function (for example: int gimmetwo(); in the header and:

int gimmetwo() {
    return 2;
}

and the result is the same :(

EDIT !!!! 11 July

After seeing answers like @k-gkinis and @nikola-dimitroff, I've understood that I have to compile different libraries for different environments.

In this case, I've created a Plugin.bundle for Mac OS x with:

Plugin.pch :

extern "C" {
    string getmytext();
}

Plugin.cpp

#include "Plugin.pch"
string getmytext() {
    return "weowoewoeowoew";
}

I built it and I imported it to Unity3D:

[DllImport ("AED")]
private static extern string getmytext ();

static void obtenerPuntos()
{
    Debug.Log (getmytext());
}

but I still get the same error !!

在这里输入图像描述

The plugin is in the right place I guess

在这里输入图像描述

What's wrong?


As seen here, make sure that you have the correct options in the inspector for the plugin.

Also, because you're targetting iOS, you must statically link the plugin, so your import attribute should be:

[DllImport ("__Internal")]

you could write

   #if UNITY_IPHONE || UNITY_XBOX360

   [DllImport ("__Internal")]

   #else

   [DllImport ("PluginName")]

   #endif

Note from the manual:

"iOS native plugins can be called only when deployed on the actual device, so it is recommended to wrap all native code methods with an additional C# code layer. This code should check Application.platform and call native methods only when the app is running on the device; dummy values can be returned when the app runs in the Editor."

So:

private static extern string getmytext();

public static string getmytextWrapper()
{
        if (Application.platform != RuntimePlatform.OSXEditor)
               return getmytext();
        else
               Debug.Log("Can't call native iOS plugin on other platforms.");
       return string.Empty;
}

and then call getmytextWrapper from somewhere in your code.

(I don't have xcode, so I can't help you much on ios)

PS The DLLImport goes above the snippet that starts with private static extern

链接地址: http://www.djcxy.com/p/27296.html

上一篇: 使用EF调用Oracle存储过程失败

下一篇: 我应该如何从Unity3D调用我的C ++函数