0

My project is to control an LCD with ST7565 controler on my Raspberry B2 I'm trying to use this c++ code, that controls the lcd: https://github.com/stephanel/ST7565-RPi

Unfortunately I'm not familiar with programming in C, because of this I want to call the c++ functions from python with ctypes.

I wrote a simple (simple for me) c++ code to use as shared library

lcdcontrol.cpp:

#include <iostream>
#include <ctime>
#include <sstream>
#include <wiringPi.h>
#include <wiringShift.h>
#include "ST7565/ST7565.cpp"

using namespace std;
ST7565 glcd(PIN_SID, PIN_SCLK, PIN_A0, PIN_RST, PIN_CS);

void start();
void drawclock();
void setpix();
void clear();
void drawstring();
void drawbitmap();

void start(){
    glcd.begin(0x18);
    glcd.display();}

void setpix() {
    glcd.setpixel(10, 10, BLACK);}

void clear() {
    glcd.clear();}

void drawstring() {
    glcd.drawstring(0, 0, "Test string");}

My python code for testing:

#!/usr/bin/python
import os
from ctypes import *
from thread import start_new_thread

lcd_lib = cdll.LoadLibrary("lcdcontrol.so")
mylcd = lcd_lib

mylcd.start()

Now I have to compile my c++ code to a shared libray. I tried several ways. But nothing works without problems. When I run the python code it returns that it can't find the "digitalwrite" function, which is a part of the wiringpi lib, or I got an error that it can't find the "start" function.

Could anybody please help me. I'm going crazy on this... Maybe there is a completely different way to use the ST7565 c++ code from python. But this seems for me as the easiest way...until now...

exert
  • 3
  • 3
  • Give Cython a look. It takes a little getting used to, but it makes calling C++ from Python very easy. – zmbq May 18 '15 at 19:59
  • 2
    "I tried several ways" and "problems" don't tell us anything. Show us how you actually compiled it, and tell us what those problems are. And show us the Python code that actually raises the error, and exactly what that error is, not just a vague description of it. – abarnert May 18 '15 at 19:59
  • 1
    Can't you just use the [RPi.GPIO](https://pypi.python.org/pypi/RPi.GPIO) Python module? See for example: [Python driving ST7565 12864 LCD](https://www.raspberrypi.org/forums/viewtopic.php?f=32&t=25029) – Lukas Graf May 18 '15 at 20:04
  • What are the dependencies of your library? Have you tried writing a small c app that simply calls funcs from the *.so*? – CristiFati May 18 '15 at 20:35
  • @Lukas: Using RPI.GPIO is possible. But unfortunately with python it is not fast enough to get a nice view at the LCD. It's "ok" with a positive LCD, but gets worse with a negative LCD (like I'm using). – exert May 19 '15 at 07:29
  • @zmbq: Thanks! Cython looks very good for me in this case. I will try it and perhaps give you a feedback if it works. – exert May 19 '15 at 07:32

2 Answers2

0

Because you're not familiar with C I assume you made the same mistake as I made for a while. You do not take care about name mangeling in C++.

See http://en.wikipedia.org/wiki/Nm_%28Unix%29

Please show how the functions are exported.

Additional information could be found here: Python: accessing DLL function using ctypes -- access by function *name* fails

Community
  • 1
  • 1
Thomas
  • 36
  • 2
  • Not finding `start` is probably related to name mangling, i.e. not declaring the C APIs as `extern "C"`. But not finding `digitalWrite` is a different linking problem. Maybe exert didn't link to the library using `-lwiringPi`. – Eryk Sun May 18 '15 at 21:17
  • Thanks for this Info. I will check the name mangeling and give a feedback. I think I found a solution for the linking problem with a modified makefile. I will check this later this day and give a feedback, too – exert May 19 '15 at 07:37
0

Thanks for the help, It works!

this is the makefile I'm using:

all:
    g++ -fPIC -shared -o lcdcontrol.so -I/usr/local/include -L/usr/local/lib -lwiringPi lcdcontrol.cpp
    sudo cp lcdcontrol.so /usr/lib/lcdcontrol.so

nm lcdcontrol.so returns:

     (...)
     U digitalWrite
     (...)
     00002968 T _Z10drawstringv
     00002a04 t _Z41__static_initialization_and_destruction_0ii
     0000293c T _Z5clearv
     00002834 T _Z5startv
     000028cc T _Z6setpixv
     0000bab6 b _ZL10xUpdateMax
     0000bab5 b _ZL10xUpdateMin
     0000bab8 b _ZL10yUpdateMax
     (...)

In my python code I can now use:

mylcd._Z5startv()
mylcd._Z6setpixv()
mylcd._Z10drawstringv()

And it works!

exert
  • 3
  • 3