myPythonClient
(below) wants to invoke a ringBell
function (loaded from a DLL using ctypes
). However, attempting to access ringBell
via its name results in an AttributeError
. Why?
RingBell.h
contains
namespace MyNamespace
{
class MyClass
{
public:
static __declspec(dllexport) int ringBell ( void ) ;
} ;
}
RingBell.cpp
contains
#include <iostream>
#include "RingBell.h"
namespace MyNamespace
{
int __cdecl MyClass::ringBell ( void )
{
std::cout << "\a" ;
return 0 ;
}
}
myPythonClient.py
contains
from ctypes import *
cdll.RingBell[1]() # this invocation works fine
cdll.RingBell.ringBell() # however, this invocation errors out
# AttributeError: function 'ringBell' not found
Perhaps because the C++ name is mangled by the compiler and not exported from the DLL as
RingBell
. Have you checked that it appears in the exported names exactly like that?Your C++ compiler is mangling the names of all externally visible objects to reflect (as well as their underlying names) their namespaces, classes, and signatures (that's how overloading becomes possible).
In order to avoid this mangling, you need an
extern "C"
on externally visible names that you want to be visible from non-C++ code (and therefore such names cannot be overloaded, nor in C++ standard can they be inline, within namespaces, or within classes, though some C++ compilers extend the standard in some of these directions).All is working now :) To summarize your posts:
Write DLL in C++:
Then you can use program link.exe to see real function name in dll. link.exe is for example in MSVC2010 here:
use:
you see Something like:
Then in python you can import it as: