301 Moved Permanently

301 Moved Permanently

how_to_use_the_thinkgear_api_in_xcode_mac_os_x.txt · Last modified: 2014/06/26 14:23 by Amine Bouchti

How to Use the ThinkGear API in Xcode (Mac OS X)

The ThinkGear Communications Driver for Mac is deprecated and will no longer be updated.

Mental Effort and Familiarity are not included in the ThinkGear Communications Driver.


Loadable modules (containing dynamic libraries or plugins) on Mac OS X are often packaged as bundles. These are generally analogous to .dll files in Windows or .so files in Linux and other *NIX platforms, though bundles also provide a richer set of functionality, e.g. facilities for loading non-executable assets such as localization strings or images.

Developers that want to integrate ThinkGear functionality into their OS X applications should utilize the CFBundle API in the Core Foundation framework to hook into ThinkGear.bundle. This document will describe the process of getting your Xcode project up and running with ThinkGear.

The NSBundle API in the Cocoa framework applies strictly to bundles containing Objective-C classes. Since ThinkGear is a C-only API, discussions of NSBundle are inappropriate in this context.

Setting up Xcode

The only requirement for loading ThinkGear.bundle is that the Core Foundation framework be included in your project's list of external frameworks and libraries. This can be done by clicking on “HelloEEG” under “TARGETS” section in your Xcode project window as shown in the following image.

Under the general tab scroll down to Linked Frameworks and Libraries, then click on the triangle to expand it. Next, click the next “+” button and Look for the CoreFoundation.framework, and then click Add.

The image below shows what your project window should look like once the Core Foundation framework has been added.

Note: If HelloEEG does not compile and you see the following error, try deleting and re-adding ThinkGear.framework under Frameworks and Libraries from the menu shown below.

  1. Click ThinkGear.framework and then click the - button.
  2. Click the + button and then click Add Other
  3. Find and add ThinkGear.framework in TG-SDK –> TG-SDK For Mac –> lib –> ThinkGear.framework

If HelloEEG is run without connecting the ThinkGear-enabled headset, the application should look like this:

Once the headset is connected, run the application once again. The application should now look like this:

If the Poor Signal data reads 0, Meditation and Attention data should be fluctuating every second. If Poor Signal reads something other than 0, re-adjust the headset accordingly until Poor Signal data goes down to 0.

At this point, you should be able to browse the code, make modifications, compile, and deploy the app to your device or emulator just like any typical OS X application.

Importing ThinkGear Functions

At the top of your header or implementation, you should include the Core Foundation library:

#include <CoreFoundation/CoreFoundation.h>

Before importing the functions, a bundle reference (CFBundleRef) must first be created for the bundle. This is constructed from a path describing the location of the bundle, which is encapsulated in a CFURLRef object. Let's first declare these objects.

CFURLRef bundleURL;
CFBundleRef thinkGearBundle;

And now, to initialize them:

bundleURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
thinkGearBundle = CFBundleCreate(kCFAllocatorDefault, bundleURL);

CFBundleCreate returns NULL if the bundleURL points to an invalid bundle, so it's a good idea to check that for validity before continuing. Note that the path above is a relative path, so the executable will need the bundle to be located in the same directory. Apple provides documentation on different ways of locating bundles

We then need to declare some function pointers that reference the functions inside ThinkGear.bundle. It is recommended to use the same naming scheme for the functions as is used in the API. A few examples are provided below for clarity. Refer to ThinkGear.h (provided in the ThinkGear SDK) for the function prototypes.

int (*TG_GetDV)()   = NULL;    // TG_GetDriverVersion
int (*TG_GetNCId)() = NULL;    // TG_GetNewConnectionId
int (*TG_Connect)(int, const char *, int, int) = NULL;

Finally, we'll want to create the references to the ThinkGear functions. This is done using the CFBundleGetFunctionPointerForName function, which takes the bundle reference as one of its parameters. This should be done for any ThinkGear functions that you plan on using in your application.

TG_GetDV   = (void*)CFBundleGetFunctionPointerForName(thinkGearBundle, 
TG_GetNCId = (void*)CFBundleGetFunctionPointerForName(thinkGearBundle, 
TG_Connect = (void*)CFBundleGetFunctionPointerForName(thinkGearBundle, 

Before using these imported functions, it is prudent to check that they were successfully imported.

   return -1;

Before your application quits (or when you're done using the functions), you'll need to release the allocated Core Foundation objects; namely, the CFURLRef and CFBundleRef objects. This is effectively equivalent to an object destructor.


Using Imported ThinkGear Functions

The imported functions can be used as if they were normally declared and implemented in your code, e.g.

int retVal = TG_Connect(connectionID, "/dev/tty.MindsetMSEM1-DevB-1", 9600, 0);
printf("TG_Connect returned: %d\n", retVal);


By reading this document, you have familiarized yourself on how to integrate the ThinkGear library into your OS X application. A sample Xcode project, implementing a simple command-line data streamer for the headset, is included in the MindKit SDK.


301 Moved Permanently

301 Moved Permanently