2015-10-03 31 views
2

我创建了一个FMOD插件上C++和生成的iOS(使用Unity3d)寄存器FMOD插件都动态库(名为.dylib)和静态库(.a)中。未能就

我能够成功地在FMOD Studio GUI中使用动态库,并且我能够在Unity3d Mac模拟器中使用它(它从Assets/Plugins中选择动态库。但是我遇到了问题对于iOS,我需要使用静态库(* .a),这意味着我必须在Unity3d(C#)中手动加载插件,生成Xcode项目并将其安装到iPhone上。我尝试在C中实现一个基本的函数,并将其加载到C#上,并且它工作正常。这意味着静态库生成正确,并且可以在iPhone上成功加载并使用它。但是我无法使用FMOD描述功能

这里是我的代码,当我在iPhone上运行它,我得到这个错误:

“FmodDescPtr is IntPtr.Zero”

在先进的感谢您的帮助!我一直在为此奋斗了5天,一直无法解决它。

C++侧:

F_DECLSPEC F_DLLEXPORT int F_STDCALL AigooGetDSPDescription2(FMOD_DSP_DESCRIPTION *FmodDesc) 
{ 

// defines the user interface, maximum distance knob 
static float distance_mapping_values[] = { 0, 1, 5, 20, 100, 500, 10000 }; 
static float distance_mapping_scale[] = { 0, 1, 2, 3, 4, 4.5, 5 }; 

// defines the 3D location attributes 
FMOD_DSP_INIT_PARAMDESC_DATA(p_3d_attributes, "3D Attributes", "", "", FMOD_DSP_PARAMETER_DATA_TYPE_3DATTRIBUTES); 


FMOD_DSP_DESCRIPTION Aigoo_Simple_Plugin_Desc = 
{ 
    FMOD_PLUGIN_SDK_VERSION, 
    "AigooSimplePlugin6", // name 
    0x00010000,  // plug-in version 
    1,    // number of input buffers to process 
    1,    // number of output buffers to process 
    Aigoo_Simple_Plugin_dspcreate, 
    Aigoo_Simple_Plugin_dsprelease, 
    Aigoo_Simple_Plugin_dspreset, 
    Aigoo_Simple_Plugin_dspread, 
    0, 
    0, 
    AIGOO_SIMPLE_PLUGIN_NUM_PARAMETERS, 
    Aigoo_Simple_Plugin_dspparam, 
    Aigoo_Simple_Plugin_dspsetparamfloat, 
    0, // Aigoo_Simple_Plugin_dspsetparamint, 
    0, // Aigoo_Simple_Plugin_dspsetparambool, 
    Aigoo_Simple_Plugin_dspsetparamdata, 
    Aigoo_Simple_Plugin_dspgetparamfloat, 
    0, // Aigoo_Simple_Plugin_dspgetparamint, 
    0, // Aigoo_Simple_Plugin_dspgetparambool, 
    Aigoo_Simple_Plugin_dspgetparamdata, 
    Aigoo_Simple_Plugin_shouldiprocess, 
    0,          // userdata 
    Aigoo_Simple_Plugin_sys_register, 
    Aigoo_Simple_Plugin_sys_deregister, 
    Aigoo_Simple_Plugin_sys_mix 
}; 


FmodDesc = &Aigoo_Simple_Plugin_Desc; 

return 9291983; //this is to test that I'm able to get this value on C# and iOS side 
} 

C#侧:

public class AigooPlugInHandler { 
    [DllImport ("__Internal")] 
    public static extern int AigooGetDSPDescription2(out IntPtr FmodDesc); 
} 

public class MyAigooClass : MonoBehaviour 
{ 
    if (Application.platform == RuntimePlatform.IPhonePlayer) { 
     IntPtr FmodDescPtr; 
     plugin_result = AigooPlugInHandler.AigooGetDSPDescription2(out FmodDescPtr); 
     //printing plugin_result returns 9291983 which is the value returned from C 
     if (FmodDescPtr != IntPtr.Zero) 
     { 
      DSP_DESCRIPTION FmodDesc = (DSP_DESCRIPTION)Marshal.PtrToStructure(FmodDescPtr, typeof(DSP_DESCRIPTION)); 
      FmodDesc.numinputbuffers = 1; 
      ERRCHECK(sys.registerDSP(ref FmodDesc, out mmdsp_handle)); 
     } 
     else 
      Console.WriteLine("FmodDescPtr is IntPtr.Zero");  
    } 
} 

这是DSP_DESCRIPTION原始结构:

[StructLayout(LayoutKind.Sequential)] //original: 
public struct DSP_DESCRIPTION 
{ 
    public uint pluginsdkversion;       /* [w] The plugin SDK version this plugin is built for. set to this to FMOD_PLUGIN_SDK_VERSION defined above. */ 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] 
    public char[]      name;    /* [w] Name of the unit to be displayed in the network. */ 
    public uint      version;   /* [w] Plugin writer's version number. */ 
    public int       numinputbuffers; /* [w] Number of input buffers to process. Use 0 for DSPs that only generate sound and 1 for effects that process incoming sound. */ 
    public int       numoutputbuffers; /* [w] Number of audio output buffers. Only one output buffer is currently supported. */ 
    public DSP_CREATECALLBACK   create;    /* [w] Create callback. This is called when DSP unit is created. Can be null. */ 
    public DSP_RELEASECALLBACK   release;   /* [w] Release callback. This is called just before the unit is freed so the user can do any cleanup needed for the unit. Can be null. */ 
    public DSP_RESETCALLBACK   reset;    /* [w] Reset callback. This is called by the user to reset any history buffers that may need resetting for a filter, when it is to be used or re-used for the first time to its initial clean state. Use to avoid clicks or artifacts. */ 
    public DSP_READCALLBACK   read;    /* [w] Read callback. Processing is done here. Can be null. */ 
    public DSP_PROCESS_CALLBACK  process;   /* [w] Process callback. Can be specified instead of the read callback if any channel format changes occur between input and output. This also replaces shouldiprocess and should return an error if the effect is to be bypassed. Can be null. */ 
    public DSP_SETPOSITIONCALLBACK  setposition;  /* [w] Setposition callback. This is called if the unit wants to update its position info but not process data. Can be null. */ 

    public int       numparameters;  /* [w] Number of parameters used in this filter. The user finds this with DSP::getNumParameters */ 
    public IntPtr      paramdesc;   /* [w] Variable number of parameter structures. */ 
    public DSP_SETPARAM_FLOAT_CALLBACK setparameterfloat; /* [w] This is called when the user calls DSP.setParameterFloat. Can be null. */ 
    public DSP_SETPARAM_INT_CALLBACK setparameterint; /* [w] This is called when the user calls DSP.setParameterInt. Can be null. */ 
    public DSP_SETPARAM_BOOL_CALLBACK setparameterbool; /* [w] This is called when the user calls DSP.setParameterBool. Can be null. */ 
    public DSP_SETPARAM_DATA_CALLBACK setparameterdata; /* [w] This is called when the user calls DSP.setParameterData. Can be null. */ 
    public DSP_GETPARAM_FLOAT_CALLBACK getparameterfloat; /* [w] This is called when the user calls DSP.getParameterFloat. Can be null. */ 
    public DSP_GETPARAM_INT_CALLBACK getparameterint; /* [w] This is called when the user calls DSP.getParameterInt. Can be null. */ 
    public DSP_GETPARAM_BOOL_CALLBACK getparameterbool; /* [w] This is called when the user calls DSP.getParameterBool. Can be null. */ 
    public DSP_GETPARAM_DATA_CALLBACK getparameterdata; /* [w] This is called when the user calls DSP.getParameterData. Can be null. */ 
    public DSP_SHOULDIPROCESS_CALLBACK shouldiprocess;  /* [w] This is called before processing. You can detect if inputs are idle and return FMOD_OK to process, or any other error code to avoid processing the effect. Use a count down timer to allow effect tails to process before idling! */ 
    public IntPtr      userdata;   /* [w] Optional. Specify 0 to ignore. This is user data to be attached to the DSP unit during creation. Access via DSP::getUserData. */ 
} 

谢谢, 卡洛斯

回答

0

看起来Aigoo_Simple_Plugin_Desc被堆叠,而不是堆中的分配。

相反的:

FMOD_DSP_DESCRIPTION Aigoo_Simple_Plugin_Desc = ... 

...尝试以下操作。注意如何FMOD_DSP_DESCRIPTION参数已更改为指针的指针

F_DECLSPEC F_DLLEXPORT int F_STDCALL 
AigooGetDSPDescription2(FMOD_DSP_DESCRIPTION **ppFmodDesc) 
{ 
    FMOD_DSP_DESCRIPTION* Aigoo_Simple_Plugin_DescPtr = new FMOD_DSP_DESCRIPTION(); 
    // initialise Aigoo_Simple_Plugin_DescPtr 
    . 
    . 
    . 
    *ppFmodDesc = Aigoo_Simple_Plugin_DescPtr; 
    . 
    . 
    . 

The specified structure must be blittable or have layout information

尝试增加[StructLayout(LayoutKind.Explicit)]对C#侧的结构。

+0

嗨@Roy感谢您的回复。以前的错误是固定的,但是我得到一个新的错误:'ArgumentException:指定的结构必须是blittable或者有布局信息' –

+0

调试缩小了这个调用的错误:'\t \t \t \t DSP_DESCRIPTION FmodDesc =(DSP_DESCRIPTION) Marshal.PtrToStructure(FmodDescPtr,typeof(DSP_DESCRIPTION)); ' –

+0

@CarlosChacon太好了!请参阅编辑您的新问题的建议 – MickyD