SharedMem Ops C++ Compilation Issues

I’m looking into building a C++ application that uses the ‘SharedMemTOP’ - [url]https://docs.derivative.ca/Shared_Mem_Out_TOP[/url] to receive a live video stream from touchdesigner on Windows. There are numerous reasons why I am pursuing the SharedMem approach instead of something seemingly simpler such as spout, but I am not considering options in this thread. What is of concern is actual implementation on the C++ side of a SharedMem interface.

Touchdesign comes with example c++ classes intended to act as the receiving end of the SharedMem TOP or CHOP. As indicated here [url]https://docs.derivative.ca/Write_a_Shared_Memory_TOP[/url], this code can be found at:

C:\Program Files\Derivative\TouchDesigner099\Samples\SharedMem

I created an example application with MS Visual Studio Community 2017 v. 15.9.4. Including the example code in my project and initializing the classes fails to compile. After several fixups - missing includes and security warnings, the code can compile but instantly ‘asserts’ with no indication of why - presumably that it is not running WIN32 - potentially meaning that either this isn’t intended for 64-bit operating systems or back in the old days it was intended only for Windows systems.

Bypassing the WIN32 checks leads to further compile issues.

Is the example code just in need of attention or am I missing something about how it should be used?

I am including a Visual Studio project that has the initial integration of a ‘hello world’ app plus the SharedMem example code included with the touchdesign install. This project will not compile on my machine and must be patched - unless I am missing something. Be advised that the files (all freely included with a standard download) bear the following licenses that may preclude me sharing it this way:

[code]/* Shared Use License: This file is owned by Derivative Inc. (Derivative) and

  • can only be used, and/or modified for use, in conjunction with
  • Derivative’s TouchDesigner software, and only if you are a licensee who has
  • accepted Derivative’s TouchDesigner license or assignment agreement (which
  • also govern the use of this file). You may share a modified version of this
  • file with another authorized licensee of Derivative’s TouchDesigner software.
  • Otherwise, no redistribution or sharing of this file, with or without
  • modification, is permitted.
    */[/code]
    SharedTOPTester.zip (10.4 KB)

Use the sample code from the 2019.10000 series of builds, it’s be cleaned up a lot. Let me know if you have any issues with that.

Can you say if the sample code from the latest unofficial releases (2019+) is backwards compatible with previous versions of touchdesigner? The version of touchdesigner I am working with is 26750.

I pulled down the latest and it looks like there are some nice LPCWSTR and string-related improvements. Thanks for pointing me towards that!

I want to point out some behavior that I see in this example code and also on the wiki which seems strange.

From the wiki (https://docs.derivative.ca/Using_Shared_Memory_in_TouchDesigner):

From the new release of UT_SharedMem.cpp:

mySharedMemInfo->lock(); UT_SharedMemInfo *info = (UT_SharedMemInfo*)mySharedMemInfo->getMemory(); if (!info) { myErrorState = UT_SHM_ERR_UNABLE_TO_MAP; mySharedMemInfo->unlock(); return false; }

What seems unusual is that the lock call can fail potentially indicating that the resource is under control from outside, but both the wiki and the source seem to behave as though the lock will always succeed. Unless I’m mistaken, in all cases the lock call should only conditionally allow access to the shared memory.

An issue that I am currently wrestling with is that, in my application, the lock indeed frequently does fail, taking a full 5 seconds before timing out, then witlessly reading the shared memory block from touchdesigner as though it was secure.

Yes, it should be backwards compatible. Yes, you are correct there should be a check on the lock, i’ll update the documentation.

Any idea why the lock is failing though? Who is holding onto the lock?

As near as I can tell - and I don’t spend 100% of my work time making native C++ apps for windows - the reason that my lock is failing bears some explanation.

When a process wants something like a mutex from the operating system in windows the OS provides a handle. I imagine, but I can’t say for sure, that TouchDesigner is holding that same handle as well. When my process gets terminated unexpectedly, say from the debugger, a crash, or a forced or otherwise unexpected termination I cannot give up my side of the handle with certainty.

Per windows documentation, If another app, say TouchDesigner, is still holding the handle, it doesn’t get closed. Thus the next time I try to open the handle it isn’t quite as available as it was before. I am not sure of the details there.

These findings seem fairly consistent though. If I change the name of the sharedmem op in TD then the handle seems to reopen and the mutex doesn’t fail anymore.

Malcolm, can you comment on the purpose of these lines found throughout the example code?

#ifdef WIN32
#ifdef WIN32
#include <windows.h>
#else
#include <libkern/OSAtomic.h>
#endif

Based on the above my best guess is that these ‘ifdefs’ are intended to allow different code to be compiled on specifically Windows or specifically OSX.

That’s correct, it’s for compiling the same code on windows vs macOS

It looks like there are lots of ‘asserts’ in the non-WIN32 code, does this code work on MacOS?

Also, in the project I working on I removed all of the ifdef/ifndef’s to allow the code to the code to compile in visual studio for the x64 platform (the only platform I intend to build for). I’m not sure what needs to be included that isn’t in some of the files…

You are correct, the code is missing macOS implementations right now.
You should leave all the ifdefs alone though. WIN32 is defined for both 32 and 64-bit builds with Visual studio.

I was unable to find a way to compile the sample code with visual studio without removing the ifdef WIN32’s because it wasn’t defined in all of the places it needs to be. This was true both of the sample code available in the release and pre-release downloads.

When the ifdefs are in the code base they add runtime crashses: assert(false)'s and compile time issues: trying to include files that aren’t on windows systems - libkern/OSAtomic.h.

quick note on your compilation issue regarding WIN32 defs: WIN32 is defined by the SDK (visual studio), and I’ve found that I need to set it manually which you can do by adding WIN32 to Project Settings → C/C++ → Preprocessor → Preprocessor Definitions

I’ve read that _WIN32 (instead of WIN32) is defined by the OS instead of the SDK so might be better? but this is at the edge of my C++ knowledge haha…

Ya I think you are correct. I’ll fix up the sample code