2015-07-04 16 views
7

Questo è un po 'difficile perché non so nemmeno se il mio C++ è ben implementato.Come dovrei chiamare la mia funzione C++ da Unity3D

Voglio chiamare una funzione da Unity3D che ho passato alcuni parametri come float *points e le mie scritture C++ in quel puntatore.

Ebbene, a partire dalla parte C++, ho scritto:

main_function.cppquesto è il mio principale funzione in C++ che funziona perfettamente in formato binario, per esempio.

#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); 
} 

Poi voglio per avvolgere il mio codice C++ a C#, quindi faccio la:

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:\Users\Rafael\Desktop\AEDlibrary\main_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); 
     }; 
    } 
} 

e 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); 
    } 
} 

ho costruirla e diventa in un AEDwrapper.dll.

Ora in Unity3D, nella parte C# (copione) che cerco di fare:

[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

So che potrei essere sbagliato nei primi passi dal mio codice, ma l'hai mai fatto prima ??? Sono un po 'perso.

Grazie in anticipo.

Rafael.


EDIT:

Ho provato con una semplice funzione (ad esempio: int gimmetwo(); nell'intestazione e:

int gimmetwo() { 
    return 2; 
} 

e il risultato è lo stesso :(

EDIT !!!! 11 luglio

Dopo aver visto risposte come @ k-gkinis e @ nikola-dimitroff, ho capito che devo compilare diverse librerie per ambienti diversi.

In questo caso, ho creato un plugin.impacchettare per Mac OS X con:

Plugin.pch:

extern "C" { 
    string getmytext(); 
} 

Plugin.cpp

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

ho costruito e ho importato a Unity3D:

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

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

ma ho ancora il stesso errore !!

enter image description here

Il plugin è nel posto giusto Credo

enter image description here

Cosa c'è di sbagliato?

+0

è possibile aggiungere il percorso completo per la DLL? è l'aspetto di problema con il file stesso ... – Proxytype

+0

Stesso problema: \ –

+0

domanda stupida ma, hai inserito la dll nella cartella dei plugin giusta? –

risposta

3

Come visto here, assicurarsi di avere le opzioni corrette nell'ispettore per il plug-in.

Inoltre, perché si sta targeting iOS, è necessario collegare in modo statico il plugin, quindi l'attributo di importazione dovrebbe essere:

[DllImport ("__Internal")] 

si potrebbe scrivere

#if UNITY_IPHONE || UNITY_XBOX360 

    [DllImport ("__Internal")] 

    #else 

    [DllImport ("PluginName")] 

    #endif 

nota dal manuale:

"I plug-in nativi di iOS possono essere chiamati solo quando vengono distribuiti sul dispositivo effettivo, quindi è consigliabile avvolgere tutti i metodi di codice nativo con un ulteriore strato di codice C#. ld controlla Application.platform e chiama i metodi nativi solo quando l'app è in esecuzione sul dispositivo; valori fittizi possono essere restituiti quando l'app viene eseguito nell'editor "

Quindi:..

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; 
} 

e quindi chiamare getmytextWrapper da qualche parte nel vostro codice

(non ho Xcode, così non posso fare molto di iOS)

PS il dllImport va al di sopra dello snippet che inizia con private static extern

+0

solo una domanda ... se sto costruendo un Plugin.bundle, sto costruendo per OSXEditor, quindi dovrebbe funzionare per il caso 'Application.platform == RuntimePlatform.OSXeditor', vero? –

+0

Penso di sì, sì. –

+0

Unity3D sta dicendo 'EntryPointNotFoundException: getmytext' quando ho messo' == 'nelle tue condizioni, perché sto usando Mac OSx, ma comunque l'ho compilato per iPhone, e compilato con XCode e ha detto:> Simboli indefiniti per l'architettura armv7 : "_getmytext", referenziato da: RegisterMonoModules() in RegisterMonoModules.o –

Problemi correlati