# Symbol missing for makeRealAudioWorkgroup

**URL:** https://forum.juce.com/t/symbol-missing-for-makerealaudioworkgroup/58717
**Category:** General JUCE discussion
**Created:** [November 8, 2023, 5:14pm UTC](https://forum.juce.com/t/symbol-missing-for-makerealaudioworkgroup/58717 "2023-11-08T17:14:09Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![abrykt](https://avatars.discourse-cdn.com/v4/letter/a/a4c791/32.png) [@abrykt](https://forum.juce.com/u/abrykt)
#### Post date: [November 8, 2023, 5:14pm UTC](https://forum.juce.com/t/symbol-missing-for-makerealaudioworkgroup/58717/1 "2023-11-08T17:14:09Z")

</div>

I can see that the below method compiles as an mm file, but if I include the header where this one is declared from a file that is compiled as a .cpp file, then I get a linker error saying that there is no symbol for `makeRealAudioWorkgroup`. If I remove the `os_workgroup_t` from the signature of this function then the linker error goes away.

I am guessing that `os_workgroup_t` is different if compiled as objective-c compared to when compiled as c++.

```auto
AudioWorkgroup makeRealAudioWorkgroup (os_workgroup_t handle)
{
    if (handle == nullptr)
        return AudioWorkgroup{};

    return AudioWorkgroup { [provider = AudioWorkgroup::WorkgroupProvider { handle }] { return &provider; } };
}

```

See:

> <https://github.com/juce-framework/JUCE/blob/master/modules/juce_audio_basics/native/juce_AudioWorkgroup_mac.h#L32>

and:

> <https://github.com/juce-framework/JUCE/blob/master/modules/juce_audio_basics/utilities/juce_AudioWorkgroup.cpp#L211>

---

<div class="post-metadata">

### Author: ![reuk](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/reuk/32/21494_2.png) [@reuk](https://forum.juce.com/u/reuk)
#### Post date: [November 8, 2023, 5:31pm UTC](https://forum.juce.com/t/symbol-missing-for-makerealaudioworkgroup/58717/2 "2023-11-08T17:31:55Z")

</div>

juce\_AudioWorkgroup\_mac.h is not intended to be included directly by users. Instead, you can retrieve a workgroup by calling `AudioIODevice::getWorkgroup()`, `AudioDeviceManager::getDeviceAudioWorkgroup()`, or override `AudioProcessor::audioWorkgroupContextChanged()`.

---

<div class="post-metadata">

### Author: ![abrykt](https://avatars.discourse-cdn.com/v4/letter/a/a4c791/32.png) [@abrykt](https://forum.juce.com/u/abrykt)
#### Post date: [November 8, 2023, 5:52pm UTC](https://forum.juce.com/t/symbol-missing-for-makerealaudioworkgroup/58717/3 "2023-11-08T17:52:11Z")

</div>

ok, our plugin requires a separate process that talks to hardware. So I would like to resuse as much as possible when joining the thread in the other process to the same audio work group as the one in the DAW. So somehow I need to signal which audio work group that the plugin has and then join any thread in the other process to the same group. Or maybe this is not the best way?

Any guidance is appreciated.

---

<div class="post-metadata">

### Author: ![reuk](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/reuk/32/21494_2.png) [@reuk](https://forum.juce.com/u/reuk)
#### Post date: [November 8, 2023, 6:08pm UTC](https://forum.juce.com/t/symbol-missing-for-makerealaudioworkgroup/58717/4 "2023-11-08T18:08:44Z")

</div>

I don’t think that’s directly possible. I would expect that a `os_workgroup_type*` is local to a specific process in the absense of documentation suggesting otherwise. Trying to read the same pointer address across process boundaries will probably result in undefined behaviour.

As an alternative, perhaps you could open the audio device in the separate process, and then get the workgroup from the audio device there. That said, once you have the audio device open, you’d only need the workgroup if you needed additional threads besides the audio thread, all sharing the same deadline.

---

<div class="post-metadata">

### Author: ![abrykt](https://avatars.discourse-cdn.com/v4/letter/a/a4c791/32.png) [@abrykt](https://forum.juce.com/u/abrykt)
#### Post date: [November 9, 2023, 8:21am UTC](https://forum.juce.com/t/symbol-missing-for-makerealaudioworkgroup/58717/5 "2023-11-09T08:21:08Z")

</div>

From [Understanding Audio Workgroups | Apple Developer Documentation](https://developer.apple.com/documentation/audiotoolbox/workgroup_management/understanding_audio_workgroups/)

> An audio workgroup is a collection of real-time threads that work together to produce audio by a common deadline while spanning multiple processes …

---

<div class="post-metadata">

### Author: ![reuk](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/reuk/32/21494_2.png) [@reuk](https://forum.juce.com/u/reuk)
#### Post date: [November 9, 2023, 11:14am UTC](https://forum.juce.com/t/symbol-missing-for-makerealaudioworkgroup/58717/6 "2023-11-09T11:14:45Z")

</div>

For audio apps and AU plugins, there are dedicated APIs to fetch the correct os\_workgroup. My point was that the docs don’t say that it’s valid to share a given os\_workgroup\_t across process boundaries, so I don’t think that approach will work.

Looking at the docs, there is [os\_workgroup\_create\_with\_port](https://developer.apple.com/documentation/os/3548469-os_workgroup_create_with_port) and [os\_workgroup\_copy\_port](https://developer.apple.com/documentation/os/3548467-os_workgroup_copy_port). The docs for those functions explicitly mention other processes, so that’s probably a good starting point.

---

<div class="post-metadata">

### Author: ![abrykt](https://avatars.discourse-cdn.com/v4/letter/a/a4c791/32.png) [@abrykt](https://forum.juce.com/u/abrykt)
#### Post date: [November 9, 2023, 3:59pm UTC](https://forum.juce.com/t/symbol-missing-for-makerealaudioworkgroup/58717/7 "2023-11-09T15:59:17Z")

</div>

Ok, thanks!

---

<div class="post-metadata">

### Author: ![abrykt](https://avatars.discourse-cdn.com/v4/letter/a/a4c791/32.png) [@abrykt](https://forum.juce.com/u/abrykt)
#### Post date: [November 22, 2023, 10:51am UTC](https://forum.juce.com/t/symbol-missing-for-makerealaudioworkgroup/58717/8 "2023-11-22T10:51:21Z")

</div>

Using `os_workgroups_copy_port` and then creating a new workgroup in the same process with `os_workgroup_create_with_port` works, but if I just use the value of the port (`mach_port_t` is an `unsigned int`) in an another process then `os_workgroup_create_with_port` returns a `nullptr`. I wonder If I need to do something else before I can use that port in some other process?

[`os_workgroup_create_with_port`](https://developer.apple.com/documentation/os/3548469-os_workgroup_create_with_port) says _A process may export its workgroup’s Mach port to coordinate any work it’s doing with similar work happening in other processes._

What does “export” mean in this case?

---

<div class="post-metadata">

### Author: ![reuk](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/reuk/32/21494_2.png) [@reuk](https://forum.juce.com/u/reuk)
#### Post date: [November 22, 2023, 11:02am UTC](https://forum.juce.com/t/symbol-missing-for-makerealaudioworkgroup/58717/9 "2023-11-22T11:02:45Z")

</div>

I don’t think we’ve tried this use-case, so I’m not sure how this is supposed to work. I’d assume that just using the same port value would be sufficient, but it sounds like that’s not the case.

If you have an Apple developer account, you will have an allowance of code-level support requests (more details [here](https://developer.apple.com/support/technical/)) - perhaps you could use one of your TSIs to answer this question.

---

<div class="post-metadata">

### Author: ![abrykt](https://avatars.discourse-cdn.com/v4/letter/a/a4c791/32.png) [@abrykt](https://forum.juce.com/u/abrykt)
#### Post date: [January 25, 2024, 4:17pm UTC](https://forum.juce.com/t/symbol-missing-for-makerealaudioworkgroup/58717/10 "2024-01-25T16:17:21Z")

</div>

Hey, I managed to get something working here. Could you please take a look at this:

> <https://github.com/juce-framework/JUCE/commit/b25574854c5e4156cef2796d9734a4e6103cc1a7>
>
> Build targets:
> \* workgroup\_master
> \* AudioPluginExample\_Standalone
> 
> 1. Start the …standalone from command line (to see logging).
> 
> This will create and register a port that the other process can use to
> send the mach\_port that represents the audio workgroup.
> 
> 2. Start 'workgroup\_master'
> This will create the audio workgroup, look for the registered port, and
> then send the audio workgroup with the port to the standalone.

This works in all targets except for AU. For AU the call to `mach_port_deallocate` gives me this:  
`[1] 58481 killed auval -v aufx Dem0 Juce`
