# Programmer sound on Nintendo Switch

**URL:** <https://qa.fmod.com/t/programmer-sound-on-nintendo-switch/15151>\
**Category:** Unity\
**Created:** [October 21, 2019, 3:58pm UTC](https://qa.fmod.com/t/programmer-sound-on-nintendo-switch/15151 "2019-10-21T15:58:17Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![GSolvberg](https://avatars.discourse-cdn.com/v4/letter/g/c89c15/32.png) [@GSolvberg](https://qa.fmod.com/u/GSolvberg)\
**Post date:** [October 21, 2019, 3:58pm UTC](https://qa.fmod.com/t/programmer-sound-on-nintendo-switch/15151/1 "2019-10-21T15:58:17Z")

</div>

Hello  
I recently started porting our game to Nintendo Switch, and I’m running into some problems regarding programmer sounds.

When playing dialogues in the game, I use this code to pass on the dialogue name:

DialogUserData d = new DialogUserData(key, speakerType, notify); GCHandle stringHandle = GCHandle.Alloc(d, GCHandleType.Pinned); dialogueInstance.setUserData(GCHandle.ToIntPtr(stringHandle)); dialogueInstance.setCallback(dialogueCallback);

DialogueUserData is a struct that looks like this:  
`
[StructLayout(LayoutKind.Sequential)]
struct DialogUserData {
public string Key;
public int Speaker;
public uint NotifyIndex;`

```
        public DialogUserData(string key, int speaker, uint onNotify) {
            Key=key;
            NotifyIndex = onNotify;
            Speaker = speaker;
        }

```

}

This works great on desktop, but when I try this code on the switch I get the following error:

ArgumentException: Object contains non-primitive or non-blittable data.  
at System.Runtime.InteropServices.GCHandle.GetTargetHandle (System.Object obj, System.Int32 handle, System.Runtime.InteropServices.GCHandleType type) [0x00000] in \<00000000000000000000000000000000\>:0  
at System.Runtime.InteropServices.GCHandle…ctor (System.Object value, System.Runtime.InteropServices.GCHandleType type) [0x00000] in \<00000000000000000000000000000000\>:0  
at System.Runtime.InteropServices.GCHandle.Alloc (System.Object value, System.Runtime.InteropServices.GCHandleType type) [0x00000] in \<00000000000000000000000000000000\>:0  
at Scripts.Bjorn.AudioManager.PlayDialog (System.String key, UnityEngine.GameObject go, System.Boolean is3D, Scripts.Bjorn.AudioManager+EventNotifyDelegate onNotify, System.Int32 speakerType) [0x00000]

Im guessing this has to do with the string not being a blittable value, however I did try pass on just a string instead of a struct to test if that would work, and it did not produce an error. Why is this the case?  
Even though passing a simple string worked, I still got another error further down:

NotSupportedException: To marshal a managed method, please add an attribute named ‘MonoPInvokeCallback’ to the method definition.  
at FMOD.Studio.EventInstance.FMOD\_Studio\_EventInstance\_SetCallback (System.IntPtr \_event, FMOD.Studio.EVENT\_CALLBACK callback, FMOD.Studio.EVENT\_CALLBACK\_TYPE callbackmask) [0x00000] in \<00000000000000000000000000000000\>:0  
at FMOD.Studio.EventInstance.setCallback (FMOD.Studio.EVENT\_CALLBACK callback, FMOD.Studio.EVENT\_CALLBACK\_TYPE callbackmask) [0x00000] in \<00000000000000000000000000000000\>:0  
at Scripts.Bjorn.AudioManager.PlayDialog (System.String key, UnityEngine.GameObject go, System.Boolean is3D, Scripts.Bjorn.AudioManager+EventNotifyDelegate onNotify, System.Int32 speakerType) [0x00000]

So I guess I have two problems:

1. How do I pass a struct (cointaining a string) as the user data for the event?
2. What is the other error that occurs with .setCallback ?

---

<div class="post-metadata">

**Author:** ![GSolvberg](https://avatars.discourse-cdn.com/v4/letter/g/c89c15/32.png) [@GSolvberg](https://qa.fmod.com/u/GSolvberg)\
**Post date:** [October 24, 2019, 7:39am UTC](https://qa.fmod.com/t/programmer-sound-on-nintendo-switch/15151/2 "2019-10-24T07:39:40Z")

</div>

So I managed to fix my first problem by changing my code to this:

> GCHandle stringHandle = GCHandle.Alloc(key, GCHandleType.Pinned);  
> DialogUserData d = new DialogUserData(GCHandle.ToIntPtr(stringHandle), speakerType, notify);  
> GCHandle dataHandle = GCHandle.Alloc(d, GCHandleType.Pinned);  
> dialogueInstance.setUserData(GCHandle.ToIntPtr(dataHandle));

where the struct looks like this:

> [StructLayout(LayoutKind.Sequential)]  
> struct DialogUserData {  
> public IntPtr Key;
> 
> ```
> public int Speaker;
> public uint NotifyIndex; 
> 
> public DialogUserData(IntPtr key, int speaker, uint onNotify) {
> Key=key;
> NotifyIndex = onNotify;
> Speaker = speaker;
> }
> 
> ```
> 
> }

Im still curious how it’s possible to pin a single string, but not a struct containing a string though.

I found a solution to the other problem in another thread here on the forum. Adding the attribute [AOT.MonoPInvokeCallback (typeof (FMOD.Studio.EVENT\_CALLBACK))] above my callback function was all I needed to do.  
I think this should be included in the scripting examples for future reference.

---

<div class="post-metadata">

**Author:** ![cameron-fmod](https://yyz2.discourse-cdn.com/flex036/user_avatar/qa.fmod.com/cameron-fmod/32/261_2.png) [@cameron-fmod](https://qa.fmod.com/u/cameron-fmod)\
**Post date:** [October 29, 2019, 10:07pm UTC](https://qa.fmod.com/t/programmer-sound-on-nintendo-switch/15151/3 "2019-10-29T22:07:00Z")

</div>

The examples should have included:

> [AOT.MonoPInvokeCallback (typeof (FMOD.Studio.EVENT\_CALLBACK))]

Thanks for pointing that out, I have fixed this for the upcoming release.
