Numpy C API: Verknüpfen Sie mehrere Objektdateien

8

Ich verwende die C-API von numpy, um einige Funktionen für die Matrixberechnung zu schreiben. Heute wollte ich einige Teile meiner Funktionen in eine separate .c-Datei verschieben und eine Kopfzeile verwenden, um sie zu deklarieren. Jetzt habe ich ein seltsames Problem, das mit der Funktion import_array von numpy zu tun hat. Ich habe versucht, das Problem so weit wie möglich zu vereinfachen. Zuerst gibt es das Arbeitsprogramm:

meintest.c

%Vor%

meintest.h

%Vor%

Makefile

%Vor%

Alles funktioniert wie erwartet. Ich kann make aufrufen und dann das Modul laden und die Funktion aufrufen:

test.py

%Vor%

Wenn ich import_array von der init-Funktion entfernen würde, gäbe es einen segfault, was das Verhalten ist, das in vielen Mailinglisten und Foren gemeldet wurde.

Nun möchte ich nur die ganze Funktion my_sub_function von meintest.c entfernen und in eine Datei namens sub.c verschieben:

%Vor%

Das neue Makefile lautet:

%Vor%

Wenn ich versuche, das Modul zu laden und die Funktion jetzt aufzurufen, gibt mir der Funktionsaufruf einen segfault. Ich kann das Problem lösen, wenn ich einen Aufruf von import_array an den Anfang von my_sub_function setze, aber ich denke nicht, dass diese Funktion so verwendet werden sollte.

Also würde ich gerne wissen, warum das passiert und was die "saubere" Art ist, ein numpiges Modul in mehrere Quelldateien aufzuteilen.

    
blogsh 03.09.2012, 19:59
quelle

1 Antwort

8

Standardmäßig stellt die import_array -Routine die NumPy C-API nur in einer einzigen Datei zur Verfügung. Dies liegt daran, dass es durch eine Tabelle von Funktionszeigern arbeitet, die in einer statischen globalen Variablen gespeichert sind (d. H. Nicht exportiert und nur innerhalb derselben Datei sichtbar).

Wie in der Dokumentation erwähnt , Sie kann dieses Verhalten mit einigen Präprozessor-Definitionen ändern:

  1. Definieren Sie in allen Dateien für Ihre Erweiterung PY_ARRAY_UNIQUE_SYMBOL für eine eindeutige Variable, die wahrscheinlich keinen Konflikt mit anderen Erweiterungen verursacht. Es wäre eine gute Idee, den Namen der Erweiterung in den Variablennamen aufzunehmen.

  2. Definieren Sie das Symbol% ​​co_de%

  3. in jeder Datei außer in der Datei, in der Sie import_array aufrufen

Diese Symbole müssen definiert werden, bevor Sie NO_IMPORT_ARRAY einfügen, damit sie wirksam werden.

    
James Henstridge 04.09.2012, 08:35
quelle

Tags und Links