Help with registering callbacks and unresolved symbols

178 views
Skip to first unread message

Mark Melvin

unread,
Jul 23, 2011, 11:53:50 PM7/23/11
to cython...@googlegroups.com
Hi There,

I figured I would start a new thread to address my new problem mentioned in the previous thread I started.

I am trying to use Cython to wrap a C++ library (for the Saleae logic analyzer) on Windows (.dll + .lib).  I have finally got it to sort of work using the MSVC compiler instead of MinGW.  It looks like I can wrap a simple function in the external library that takes no arguments.  However, now I am trying to register a callback, and I am getting an unresolved symbol error when linking.  

The .h file provided by Saleae contains the following:
.
.
typedef signed long long int S64;
.
.
#if defined(API_RELEASE)
#if defined(WIN32)
#define SALEAE_DEVICE_API __declspec(dllexport)
#else
#define SALEAE_DEVICE_API __attribute__ ((visibility("default")))
#define __stdcall
#endif
#else
#define SALEAE_DEVICE_API
#ifndef WIN32
#define __stdcall
#endif
#endif

class SALEAE_DEVICE_API DevicesManagerInterface
{
public:
static void BeginConnect();  //Call this function to start connecting to Logic.  Wait for a OnConnect callback before talking with Logic.
static void RegisterOnConnect( void (__stdcall *callback)( U64 device_id, GenericInterface* device_interface, void* user_data ), void* user_data = NULL ); //Callback registration
static void RegisterOnDisconnect( void (__stdcall *callback)( U64 device_id, void* user_data ), void* user_data = NULL );  //Callback registration
static void DeleteU8ArrayPtr( U8* array_ptr ); //use this to delete memory provided to you from the SDK. i.e. In Logic's OnReadData callback

private:
static bool mInitVar;
static bool InitFunc();
};


I can successfully wrap and call the "BeginConnect" method, but now I am struggling with the "RegisterOnConnect" method.  Here is my current .pyx file:

cdef extern from "SaleaeDeviceApi.h":
    cdef cppclass GenericInterface

    ctypedef unsigned long long int U64

cdef extern from "SaleaeDeviceApi.h" namespace "DevicesManagerInterface":
    cdef void BeginConnect()
    cdef void RegisterOnConnect( void (__stdcall *callback)( U64 device_id, GenericInterface* device_interface, void* user_data ), void* user_data = NULL )


cdef public void __stdcall OnConnect(U64 device_id, GenericInterface* device_interface, void* user_data ):
    print "Yo!"

cdef test():
    RegisterOnConnect(&OnConnect)
    BeginConnect()

def run_test():
    test()

This compiles fine, but fails linking with the following error:

C:\_work\scripts\python\saleae>c:\python27\python setup.py build_ext --inplace
running build_ext
cythoning test.pyx to test.cpp
building 'SaleaeDeviceApi' extension
C:\Program Files\Microsoft Visual Studio 10.0\VC\BIN\cl.exe /c /nologo /Ox /MD /W3 /GS- /DNDEBUG -IC:\_work\scripts\python\saleae -Ic:\python27\include -Ic:\python27\PC /Tptest.cpp /Fobuild\temp.win32-2.7\Release\test.obj
test.cpp
c:\_work\scripts\python\saleae\test.cpp(467) : warning C4700: uninitialized local variable '__pyx_v_ptr' used
C:\Program Files\Microsoft Visual Studio 10.0\VC\BIN\link.exe /DLL /nologo /INCREMENTAL:NO /LIBPATH:C:\_work\scripts\python\saleae /LIBPATH:c:\python27\libs /LIBPATH:c:\python27\PCbuild SaleaeDevice.lib /EXPORT:initSaleaeDeviceApi build\temp.win32-2.7\Release\test.obj /OUT:C:\_work\scripts\python\saleae\SaleaeDeviceApi.pyd /IMPLIB:build\temp.win32-2.7\Release\SaleaeDeviceApi.lib /MANIFESTFILE:build\temp.win32-2.7\Release\SaleaeDeviceApi.pyd.manifest
   Creating library build\temp.win32-2.7\Release\SaleaeDeviceApi.lib and object
build\temp.win32-2.7\Release\SaleaeDeviceApi.exp
test.obj : error LNK2019: unresolved external symbol "public: static void __cdecl DevicesManagerInterface::RegisterOnConnect(void (__cdecl*)(unsigned __int64,class GenericInterface *,void *),void *)" (?RegisterOnConnect@DevicesManagerInterface@@SAXP6AX_KPAVGenericInterface@@PAX@Z2@Z) referenced in function "struct _object * __cdecl __pyx_f_15SaleaeDeviceApi_test(void)" (?__pyx_f_15SaleaeDeviceApi_test@@YAPAU_object@@XZ)
C:\_work\scripts\python\saleae\SaleaeDeviceApi.pyd : fatal error LNK1120: 1 unresolved externals
error: command '"C:\Program Files\Microsoft Visual Studio 10.0\VC\BIN\link.exe"'
 failed with exit status 1120

I don't quite understand why there is an unresolved symbol.  I originally thought that it was Cython making my function __cdecl instead of __stdcall, but if I check the generated C code, my functions were generated properly with __stdcall in front.  Does anyone have any ideas as to what my be going wrong here?  It is obviously finding and linking with the SaleaeDevice library properly because it looks like the function DevicesManagerInterface::BeginConnect() wraps just fine.

I am using Python 2.7 on Windows XP, 32-bit.

Thanks in advance,
Mark.

Robert Bradshaw

unread,
Jul 26, 2011, 12:48:53 AM7/26/11
to cython...@googlegroups.com

So it sounds like Cython is doing the right thing here, or at least
correctly propagating your specifications.

> Does anyone have any ideas as to what my be going
> wrong here?  It is obviously finding and linking with the SaleaeDevice
> library properly because it looks like the
> function DevicesManagerInterface::BeginConnect() wraps just fine.
> I am using Python 2.7 on Windows XP, 32-bit.

There are some people on this list with Windows experience, but you
might have better luck finding a solution on the distutils mailing
list, or python...@python.org, or even a general Windows developer
list. (Cutting the file down to a small chunk of relevant code might
be useful for these folks.

- Robert

Mark Melvin

unread,
Jul 26, 2011, 10:03:43 AM7/26/11
to cython...@googlegroups.com
Hi Robert,

Thanks for the reply.  I just managed to get my callback to work.  It turns out I needed to add a "/D WIN32" to the compile command line due to the way the include file is structured.  This is pretty sweet.  I can't wait to start messing around with this.  Thanks for an awesome tool!

Regards,
Mark.

Robert Bradshaw

unread,
Jul 26, 2011, 12:10:33 PM7/26/11
to cython...@googlegroups.com

Ah. I would have had no idea... Thanks for following up, hopefully
others who run across this issue will be able to find your solution as
well.

> This is pretty sweet.  I can't wait to
> start messing around with this.  Thanks for an awesome tool!

Glad you're finding it useful!

- Robert

Reply all
Reply to author
Forward
0 new messages