2017-03-16 29 views
1

cgoを構造体配列に使用する際に問題があります。次のようにcgo構造体配列を使用して値を代入する

私のプログラム:

は、私はC言語で構造体を持っているし、C構造体配列へのポインタが含まれています。

Cでは、変数のメモリをmallocするために、initialize関数(変数へのポインタ、変数内の配列の長さという2つのパラメータを取る)を提供します。

次に、この変数に値を割り当て、変数の配列に値を割り当てます。そして、私はこの変数を使うために別のC関数を呼び出します。

C関数がそれを処理した後。変数をもう一度ピックアップして、他のGo関数に戻ります。

このようにコード化すると、私は次のような配列になります。 type * C.structはインデックス作成をサポートしていません。

私のコードは以下のとおりです。

C:

TEST.H

typedef struct 
{ 
    int  profileCnt; 
    _profile *profile;      //pointer to profile array 
}_profiles; 
// variable using in Go 


typedef struct 
{ 
    int  profileId;    
    _name userName;    
    char   *dateOfBirth;   
    int  stateFipsId;    
}_profile; 

typedef struct 
{ 
    char first[32]; 
    char last[32]; 
} _name; 


void initializeProfiles(_profiles *profiles, int profileCount, bool create); 
int doSomething _In_C(_profiles *profiles, int log); 

test.cの

void initializeProfiles(_profiles *profiles, int profileCount, bool create) 
{ 

    profiles->profileCnt = profileCount;             
// initialize profiles struct & profile[] Array 

    if (profileCount > 0) 
    { 
     if (create == true) 
      profiles->profile = malloc(profileCount * sizeof *profiles->profile + 1);   // allocate memory for profiles[numProfiles] 

      for (int i = 0; i < profiles->profileCnt; i++) 
      initializeProfile(&profiles->profile[i], create); 

     if (create == false) 
     { 
      free(profiles->profile); 
      profiles->profileCnt = 0; 
     } 
    } 
    else 
     profiles->profile = NULL; 

} 

void initializeProfile(_profile *profile, bool create) 
{ 
    if (create == true) 
    {  
     profile->dateOfBirth = NULL;    
    } 

    profile->profileId = 0;     
    memset(profile->userName.first, '\0', sizeof(profile->userName.first));  
    memset(profile->userName.last, '\0', sizeof(profile->userName.last));  

    if (create == false) 
    { 
     if (profile->dateOfBirth != NULL) 
      free(profile->dateOfBirth); 
    } 
} 



int doSomething _In_C(_profiles *profiles, int log) 
{ 

    /* =========================================== 



    */ ==== did something to that variable============================ 

    if (errStatus.code == _SUCCESS) 
     return(_SUCCESS); 
    else 
     return(FAILURE); 
} 

マイGOコード

package main 
//#cgo CFLAGS: -std=c99 -ggdb3 -O0 -Wall 
//#cgo CFLAGS: -I../../include/common 
//#cgo LDFLAGS: -L string.h 
//#cgo LDFLAGS: -lstdc++ -lpthread -lm -lc -lssl -lcrypto 
//#include <stdio.h> 
//#include <stdlib.h> 
//#include "test.h" 
import "C" 


//import "unsafe" 

func Test() { 

    log := 1 // sets logging level 
    numProfiles := 3 

    var profiles C._profiles 

    C.initializeProfiles(&profiles, C.int(numProfiles), C.bool(true)) 


    profiles.profile[0].profileId = C.int(2) 
    profiles.profile[0].stateFipsId = C.int(1) 
    profiles.profile[0].userName.first = C.CString("test") 
    profiles.profile[0].userName.last = C.CString("test") 

    C.dosomething_In_C(&profiles,C.int(3)) 

    C.initializeProfiles(&profiles, C.int(numProfiles), C.bool(false)) 


    fmt.Println(int("get c variable and return") 
} 

私はこの profiles.profiようでコンパイルル[0] .profileId = C.int(2)

Iましたエラーメッセージ: 無効な操作:profiles.profile [0](タイプ* C.struct ___ 6はインデックスをサポートしていません)ので

、I別の解決策を試してください。移動するには、C構造体配列フォームを転送します。この

profile.profikes = (*[1 << 30]C._profile)(unsafe.Pointer(&profiles.profile))[:numProfiles:numProfiles] 

のようなしかし、使用することはできませんのようなエラーが発生します([1073741824] C.struct * ___ 6)(unsafe.Pointer(& profiles.profile))[:numProfiles:numProfiles](入力し[] C.struct ___ 6)などタイプ* C.struct ___ 6 in assignment

私はdosomething_In_C関数を呼び出すと別のメモリを作成しますが、データを取得できません。

これを修正する方法は誰にも分かりますか?

はあなたに

答えて

0

することはできませんインデックスC配列をありがとう、そしてあなたは、Cの構造体への移動スライスを割り当てることはできませんが、新しいスライスが同じメモリ領域を参照するので、する必要はありません。

p := (*[1 << 30]C._profile)(unsafe.Pointer(profiles.profile))[:numProfiles:numProfiles] 

p[0].profileId = C.int(2) 
p[0].stateFipsId = C.int(1) 
p[0].userName.first = C.CString("test") 
p[0].userName.last = C.CString("test") 
+0

ありがとうございます。実際には、私は同じメモリを参照する必要があります。初期化して値を代入した後、別のC関数にパラメータとして渡す必要があるためです。いったん私は固定長配列構造体とCの構造体を使用していた、それはインデックスをサポートしています。私はprofies.profile [0] .profileId = C.int(2)のような値を割り当てることができます。しかし、動的配列にすることはできません。 –

+0

@weiZhang:分かりません。私はこれが同じメモリを参照していると言いました。ポインタをC関数に戻すことを止めるものは何もありません。これにより、単にGoのインデックス表記で配列の値にアクセスできます。 – JimB

+0

ありがとう、私は再び試してデバッグします。 –

関連する問題