Pybind11 and global C variables - pybind11

I don't manage to export a global variable from C to Python using pybind11. The problem can be reproduced from a simple example. Let's say we have a header file (global.h) like this:
#ifndef GLOBAL_H
#define GLOBAL_H
extern int array[];
#endif
The array is defined in a C file (global.c) like this:
#include "global.h"
int array[] = {1, 2, 3, 4};
I want to export this array in a Python module using pybind11 and the following C++ file (pyglobal.cpp):
#include <pybind11/pybind11.h>
extern "C"
{
#include "global.h"
}
PYBIND11_MODULE(pyglobal, m)
{
m.attr("array") = array;
}
Everything works fine when I generate my library with CMake (CMakeLists.txt):
cmake_minimum_required(VERSION 2.8.12)
project(pyglobal)
find_package(pybind11 PATHS ${PYBIND11_DIR} REQUIRED)
pybind11_add_module(pyglobal pyglobal.cpp global.c)
But when I start a python3 shell and type
import pyglobal
I get the following error message:
> Python 3.5.2 (default, Nov 23 2017, 16:37:01)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pyglobal
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: AttributeError: array
What am I doing wrong here?

That assignment is a rather unfortunate implicit cast and hence doesn't do what you think it does. The following is one way of exposing that array, assuming you have numpy installed:
#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>
extern "C"
{
#include "global.h"
}
PYBIND11_MODULE(pyglobal, m)
{
auto dtype = pybind11::dtype(pybind11::format_descriptor<int>::format());
m.attr("array") = pybind11::array(dtype, {3}, {sizeof(int)}, array, nullptr);
}
If you do not know the size, you can use an empty base array and a large (fake) size. Just be sure not to iterate over the array in anything other than a range-restricted manner. Example:
#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>
extern "C"
{
#include "global.h"
}
PYBIND11_MODULE(pyglobal, m)
{
auto dtype = pybind11::dtype(pybind11::format_descriptor<int>::format());
auto base = pybind11::array(dtype, {(unsigned)-1}, {sizeof(uintptr_t)});
m.attr("array") = pybind11::array(dtype, {(unsigned)-1}, {sizeof(int)}, array, base);
}
which can be used like so:
>>> import pyglobal
>>> for i in range(3):
... print(pyglobal.array[i])
...
1
3
0
>>>
but which for example can not be printed, as that would iterate over the full (unsigned)-1 size.

Related

SWIG wrong encoded string crashes Python

I've a problem where all my SWIG wrappers that deals with strings crashes If I pass a wrong encoded string inside a std::string, I mean strings that contains èé and so on, characters valid for the current locale, but not UTF-8 valid.
On my code side, I have solved parsing the input as wide strings and convert them to UTF-8, but I would like to catch those kind of errors with an Exception rather than a crash, isn't supposed PyUnicode_Check to fail with those strings ?
Swig actually crashes in SWIG_AsCharPtrAndSize() when calling PyString_AsStringAndSize(), this is the swig generated code:
SWIGINTERN int
SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc)
{
#if PY_VERSION_HEX>=0x03000000
#if defined(SWIG_PYTHON_STRICT_BYTE_CHAR)
if (PyBytes_Check(obj))
#else
if (PyUnicode_Check(obj))
#endif
#else
if (PyString_Check(obj))
#endif
{
char *cstr; Py_ssize_t len;
#if PY_VERSION_HEX>=0x03000000
#if !defined(SWIG_PYTHON_STRICT_BYTE_CHAR)
if (!alloc && cptr) {
/* We can't allow converting without allocation, since the internal
representation of string in Python 3 is UCS-2/UCS-4 but we require
a UTF-8 representation.
TODO(bhy) More detailed explanation */
return SWIG_RuntimeError;
}
obj = PyUnicode_AsUTF8String(obj);
if(alloc) *alloc = SWIG_NEWOBJ;
#endif
PyBytes_AsStringAndSize(obj, &cstr, &len);
#else
PyString_AsStringAndSize(obj, &cstr, &len);
#endif
if (cptr) {
Crash happens to into the last PyString_AsStringAndSize visible.
I remark that strings are passed as std::string but in happens also with const char* without any kind of difference.
Thanks in advice !
Cannot reproduce. Edit your question and add a Minimal, Complete, Verifable Example if this example doesn't solve your issue and need further help:
test.i
%module test
%include <std_string.i>
%inline %{
#include <string>
std::string func(std::string s)
{
return '[' + s + ']';
}
%}
Demo:
Python 3.3.5 (v3.3.5:62cf4e77f785, Mar 9 2014, 10:35:05) [MSC v.1600 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import test
>>> test.func('ábc')
'[ábc]'
Problem was with 3.3.0 version we were still using, updating to 3.3.7 solved the problem, in the Python release notes there's several bug fixed in regards to PyUnicode_Check

Use OpenGL in Swift project

I'm trying to move one of my apps over to using Swift. It contains an OpenGL draw loop (that also contains some Cocoa statements - yes, I realise it's probably a horrible mess of a class) so I've copied the original .m & .h files into my new project and added a *-Bridging-Header.h file. I've also added a build phase to link with the OpenGL.framework (although I'm not sure I needed to and it made no difference to the issue).
Originally I borrowed heavily from Apple's example OpneGL project and within one of the files I'm trying to compile there is:
#include "sourceUtil.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#import <OpenGL/OpenGL.h>
demoSource* srcLoadSource(const char* filepathname)
{
demoSource* source = (demoSource*) calloc(sizeof(demoSource), 1);
// Check the file name suffix to determine what type of shader this is
const char* suffixBegin = filepathname + strlen(filepathname) - 4;
if(0 == strncmp(suffixBegin, ".fsh", 4))
{
source->shaderType = GL_FRAGMENT_SHADER;
}
else if(0 == strncmp(suffixBegin, ".vsh", 4))
{
source->shaderType = GL_VERTEX_SHADER;
}
else
{
// Unknown suffix
source->shaderType = 0;
}
// more code follows
.
}
However, GL_FRAGMENT_SHADER is causing Xcode to stop any build with the error "Use of undeclared identifier 'GL_FRAGMENT_SHADER'" - similarly with the GL_VERTEX_SHADER. I presume there'll be more errors but currently this is what Xcode stops at.
You need: #import <OpenGL/gl.h>

Eclipse EXPORT DLL before compile/build

I am using Eclipse Juno updated as two days ago, fresh install and installed C/C++ and linked MinGW into Windows (7 64-bit by the way). Everything works fine, i can build/compile "Hello World" and execute the file generated by eclipse.
Now i have three files,
main.cpp:
#include "functions.cpp"
#include <iostream>
using namespace std;
int main(int){
int a = mult(20,5);
cout << "Twenty times 5 is " << a;
cout << a << "Plus 2 is " << add2(a);
return 0;
}
functions.cpp:
#include "header.h"
int EXPORT add2(int num){
return num + 2;
}
int EXPORT mult(int num1, int num2){
int product;
product = num1 * num2;
return product;
}
header.h:
#ifndef HEADER_H_
#define HEADER_H_
#ifdef BUILD_DLL
#define EXPORT __declspec(dllexport)
#else
#define EXPORT __declspec(dllimport)
#endif
int EXPORT add2(int num);
int EXPORT mult(int num1, int num2);
#endif /* HEADER_H_ */
With this set up in the code i need a DLL file to be generated first and then used when building. If i place these files on my desktop for instance, i can /cd desktop and use this command:
g++ functions.cpp -o functions.dll -DBUILD_DLL -shared -Wl,--out-implib,libfunctions.dll.a
This creates a DLL file and also a .A File, one dynamic one static.
IN SHORT MY QUESTION:
Can i get Eclipse to make a DLL file from functions.cpp before it attempts to build my code into a .exe file? At this stage my code is looking for an DLL file to IMPORT.
I found out how to do this. It may not be the best option for this, however i was able to go to my project Properties-->C/C++ Build--->Settings--->Build Steps.
This seems to work however I am now trying to find a way to set the command to use the source directory of the project instead of me having to use C:/eclipse/workplace etc.

linux usb-hid :add libhid library to eclipse(C++) or netbeans IDEs or native input.h or hiddev.h?

i have problem with libhid .
i found that there 2 way 4 accessing the usb-hid in linux
1)linux default libraries like input.h and hiddev.h and ...
2)using libhid
i found libhid some confusing and try to use input.h but i have problem with that 2.
i dont know how to get information about my device from ubuntu
i use open() to open the device
str="/dev/inpt/eventX" \\where X=0,1,...,7(I'm not sure about this)
open(str,O_RDWR)
then get info with ioctl
ioctl(fd,EVIOCGVERSION,&version);
but it give me wrong vendor and product IDs
then
i try to use libhid but had know idea how to use libhid (or any other library) in eclipse or netbeans
can you tell me how you compiled your codes any IDE like eclipse or netbeans or just using terminal and gcc?
or
how to work with ioctl() and open() ?
my whole example code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ftw.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <errno.h>
#include <stdint.h>
#include <asm/types.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/usbdevice_fs.h>
#include <linux/input.h>
#include <strings.h>
struct input_devinfo
{
uint16_t bustype;
uint16_t vendor;
uint16_t product;
uint16_t version;
};
int main(void) {
//puts("!!!Hello World!!!"); /* prints !!!Hello World!!! */
//usb_device ud;
//int i=0;
//string str;
//str=char[100];
//str="/dev/input/event0\n";
printf("------------- start -----------------\n");
char str[]="" ;
int version=0;
char c[16];
char t;
int i,fd;
//for (i=0 ; i<8 ; i++)
{
//strcpy(c,str);
//t=i-'0';
//printf("salam5\n");
//c[15]=t;
//openning
//open(str,O_RDONLY);//read and write
if ((fd = open(str,O_RDWR)) < 0)
perror("str open\n");
else
printf("%s opened successfully\n",str);
ioctl(fd,EVIOCGVERSION,&version);
printf("version = %d \n",version);
printf("evdev driver version is %d.%d.%d\n",version >> 16, (version >> 8) & 0xff, version & 0xff);
//geting info from device
struct input_devinfo device_info;
ioctl(fd,EVIOCGID,&device_info);
printf("vendor 0x%04hx product 0x%04hx version 0x%04hx is on ?",
device_info.vendor, device_info.product,
device_info.version);
}
return EXIT_SUCCESS;
}
I find a way to compile my code in eclipse
1 problem solved
to compile your code with GCC in terminal you should define libhid for GCC by adding "-lhid" to your command :
gcc test_libhid.c -lhid
if your using eclipse and you want to use libhid with it you should add "-lhid" to gcc linker in order to gcc could use libhid when its compiling your code
follow the steps:
1)on the project Explorer panel , R-click on your project select properties (last option)
or select your project and press Alt+Enter
2)in the left panel expand "c/c++ build" and select "setting"
3)in the right side select "tool setting" tab
4)you should see GCC C compiler and GCC C linker and GCC assembler in there .
expand GCC C linker and select Libraries
5)after selecting in the right side you should see 2 boxes: Libraries(-l) and Library search path(-L)
in the Libraries(-l) add "hid"
note:eclipse use GCC to compile your codes when you do this steps eclipse add "-lhid" parameter to gcc to able it recognizing the libhid.

How can I generate unique values in the C preprocessor?

I'm writing a bunch of related preprocessor macros, one of which generates labels which the other one jumps to. I use them in this fashion:
MAKE_FUNNY_JUMPING_LOOP(
MAKE_LABEL();
MAKE_LABEL();
)
I need some way to generate unique labels, one for each inner MAKE_LABEL call, with the preprocessor. I've tried using __LINE__, but since I call MAKE_LABEL inside another macro, they all have the same line and the labels collide.
What I'd like this to expand to is something like:
MAKE_FUNNY_JUMPING_LOOP(
my_cool_label_1: // from first inner macro
...
my_cool_label_2: // from second inner macro
...
)
Is there a way to generate hashes or auto-incrementing integers with the preprocessor?
If you're using GCC or MSVC, there is __COUNTER__.
Other than that, you could do something vomit-worthy, like:
#ifndef USED_1
#define USED_1
1
#else
#ifndef USED_2
#define USED_2
2
/* many many more */
#endif
#endif
I use this:
#define MERGE_(a,b) a##b
#define LABEL_(a) MERGE_(unique_name_, a)
#define UNIQUE_NAME LABEL_(__LINE__)
int main()
{
int UNIQUE_NAME = 1;
return 0;
}
... and get the following:
int main()
{
int unique_name_8 = 1;
return 0;
}
As others noted, __COUNTER__ is the easy but nonstandard way of doing this.
If you need extra portability, or for other cool preprocessor tricks, the Boost Preprocessor library (which works for C as well as C++) will work. For example, the following header file will output a unique label wherever it's included.
#include <boost/preprocessor/arithmetic/inc.hpp>
#include <boost/preprocessor/slot/slot.hpp>
#if !defined(UNIQUE_LABEL)
#define UNIQUE_LABEL
#define BOOST_PP_VALUE 1
#include BOOST_PP_ASSIGN_SLOT(1)
#undef BOOST_PP_VALUE
#else
#define BOOST_PP_VALUE BOOST_PP_INC(BOOST_PP_SLOT(1))
#include BOOST_PP_ASSIGN_SLOT(1)
#undef BOOST_PP_VALUE
#endif
BOOST_PP_CAT(my_cool_label_, BOOST_PP_SLOT(1)):
Sample:
int main(int argc, char *argv[]) {
#include "unique_label.h"
printf("%x\n", 1234);
#include "unique_label.h"
printf("%x\n", 1234);
#include "unique_label.h"
return 0;
}
preprocesses to
int main(int argc, char *argv[]) {
my_cool_label_1:
printf("%x\n", 1234);
my_cool_label_2:
printf("%x\n", 1234);
my_cool_label_3:
return 0;
}
I can't think of a way to automatically generate them but you could pass a parameter to MAKE_LABEL:
#define MAKE_LABEL(n) my_cool_label_##n:
Then...
MAKE_FUNNY_JUMPING_LOOP(
MAKE_LABEL(0);
MAKE_LABEL(1);
)
You could do this:
#define MAKE_LABEL() \
do { \
my_cool_label: \
/* some stuff */; \
goto my_cool_label; \
/* other stuff */; \
} while (0)
This keeps the scope of the label local, allowing any number of them inside the primary macro.
If you want the labels to be accessed more globally, it's not clear how your macro "MAKE_FUNNY_JUMPING_LOOP" references these labels. Can you explain?
It doesn't seem possible with a standard preprocessor, although you could fake it out by putting parameters within MAKE_LABEL or MAKE_FUNNY_JUMPING_LOOP, and use token pasting to create the label.
There's nothing preventing you from making your own preprocessing script that does the automatic increment for you. However, it won't be a standard C/C++ file in that case.
A list of commands available: http://www.cppreference.com/wiki/preprocessor/start