2014-04-17 24 views
0

我在我們的開發機器上使用Python C API編寫了一個C封裝器(它是32位,運行32位Python 2.7)。之後我必須將包裝器和C源代碼移動到另一臺64位,運行64位Python 2.6的機器上。在C包裝下面的代碼返回的64位機器上段故障,而不是32位機(它完全存在)上:如何製作一個C封裝(用32位Python編寫)在運行64位Python的新機器上工作?

static PyObject *tide3_tide_hours(PyObject *self, PyObject *args) { 
    double initHour, z0, delt; 
    char f_seasonal; 
    int numHours; 

    // Parse arguments from Python 
    if (!PyArg_ParseTuple(args, "ddsid", &initHour, &z0, 
             &f_seasonal, &numHours, &delt)) 
     return NULL; 

    // Allocate memory for zhr, which is the output we want 
    zhr = (double *) malloc ((numHours) *sizeof (double)); 

    // Call the C source code 
    int value = tide_hours(&tc, initHour, 
          z0, f_seasonal, numHours, zhr, delt); 

    // Construct the Python return object by defining 
    // a new list and looping over zhr 
    int i; 
    PyObject *l = PyList_New(0); 
    if (!l) { 
     printf("No list \n"); 
     return NULL; 
    } 

    for (i=0; i < numHours; i++) { 
     PyList_Append(l,PyFloat_FromDouble(zhr[i])); 
     //printf("%f \n",zhr[i]); 
    } 

    // Free memory and return the Python list containing zhr to Python 
    free (zhr); 

    return l; 
} 

注意& tc爲只是一個結構I類定義Python並在C包裝的開頭初始化。我想要zhr(由C源代碼中的tide_hours計算),並且如果我取消註釋for循環中的printf語句,可以看到它的正確值。如果我插入:

爲ZHR分配內存後
printf("Size of zhr: %d\n",sizeof(zhr)); 

右,我看「4」的32位機器上和「8」 64位機器上。我確信這就是代碼返回分段錯誤的原因,但我無法弄清楚如何阻止這種情況的發生。

我檢查了其餘的C封裝/ Python代碼,並將問題縮小到本節。輸入參數是正確的值和類型。如前所述,zhr是由tide_hours正確計算和輸出的(如果我在for循環中使用printf),但是與32位到64位交換機的內存分配有關。我不熟悉編寫C包裝器(這是我的第一個包裝器),所以我想知道是否有辦法解決這個問題,或者我甚至沒有想到會導致問題。如果您需要更多代碼,請提前致謝,並告知我們。

+0

我假設你重新編譯的基礎上,爲'zhr'大小的變化。你有沒有嘗試gdb?啓動程序運行,暫停輸入或睡眠。找到pid,然後運行'sudo gdb'並在gdb shell中輸入'attach '然後'繼續'。當段錯誤發生時,gdb會告訴你在哪裏(並且可能顯示一個指針== 0x0或類似的)。您正在使用'zhr'而沒有確認內存是否真正被分配,並且可能發生故障的位置。 –

+0

「zhr」在哪裏定義? (和[爲什麼你施放'malloc()']的結果?(http://stackoverflow.com/q/605845/296974)?) – glglgl

+0

@RyanP是的,我在新機器上重新編譯。我會嘗試你的建議,看看會發生什麼。 @ glglgl zhr首先被定義爲包裝器頂部的double * zhr,在我發佈的函數之外。 –

回答

-1

編輯:

兩個選擇:

1)確保您的包裝被移植到64位和重建它(也許這就是你問的幫助, - 如果是這樣,什麼是原型/實現tide_hours函數?)或

2)使用現有的32位編譯包裝器,然後您的64位機器也需要安裝32位Python C運行庫,然後你會用你的包裝。

對於一個類似的過程,閱讀:

+0

好的,我會聯繫根人。 –

+0

這實際上並非如此。這肯定比修復C代碼容易,但沒有理由不能修復C代碼。 –

相關問題