2

I'm using C extension of Python and I met with a problem in passing strings from Python to C program. Take the following as an example: The python code:

import ctypes
from ctypes import *
from numpy.ctypeslib import ndpointer
from scipy.cluster.hierarchy import dendrogram, linkage
from os import system

ls_str = [ ['a','b'] , ['c','d'] ]
for str1, str2 in ls_str:
    system('g++ -c -fPIC *.cpp -o test.o')
    system('g++ -shared -Wl,-soname,test.so -o test.so test.o')
    lib = cdll.LoadLibrary('./test.so')
    lib.Test.argtypes = [c_char_p]
    x = create_string_buffer(str1)
    y = create_string_buffer(str2)
    val = lib.Test(x,y)

The .cpp file:

#include <iostream>
#include <string>
using namespace std;

extern "C"
int Test(char *str1, char *str2){
    static string string1 = str1, string2 = str2;
    // string string1 = str1, string2 = str2;
    cout << "str1 = " << str1 << endl;
    cout << "str2 = " << str2 << endl;
    cout << "string1 = " << string1 << endl;
    cout << "string2 = " << string2 << endl;
    return 0;
}

When I define the string1 and string2 as static, I got the following output:

str1 = a
str2 = b
string1 = a
string2 = b
str1 = c
str2 = d
string1 = a
string2 = b

Then I remove the static, the output becomes:

str1 = a
str2 = b
string1 = a
string2 = b
str1 = c
str2 = d
string1 = c
string2 = d

I find that in function, say Test(), when a variable is defined as static, its value will not change even if I call Test() multiple times from Python. But I used to think that every time a call from Python finishes, the function in C program will be released. Why does this happens? Is it the target that static is designed for? Thank you all for helping me!

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
pfc
  • 1,831
  • 4
  • 27
  • 50
  • It might help if i point out that you are not running a C++ *program*, but a C++ *library*. That might seem like semantics, but the C++ runs in the same process as python - it is not a complete program (it has no `main()`). – cdarke Apr 09 '17 at 08:36

1 Answers1

2

This is expected. When declared static, they are initialized once at the first call to the function. When not static, they are initialized at every call to the function.

The function is not "released" unless the dynamic library is unloaded. I'm not sure ctypes allows explicitly unloading libraries. They should be unloaded when the refcount goes to zero, so try del lib after lib.Test.

See: How can I unload a DLL using ctypes in Python?

Community
  • 1
  • 1
szym
  • 5,606
  • 28
  • 34
  • The first paragraph of your answer is what I hope to know. Also thank you for your instruction on how to unload the libraries. Thank you! – pfc Apr 09 '17 at 11:50