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関数を呼び出すと別のメモリを作成しますが、データを取得できません。
これを修正する方法は誰にも分かりますか?
はあなたに
ありがとうございます。実際には、私は同じメモリを参照する必要があります。初期化して値を代入した後、別のC関数にパラメータとして渡す必要があるためです。いったん私は固定長配列構造体とCの構造体を使用していた、それはインデックスをサポートしています。私はprofies.profile [0] .profileId = C.int(2)のような値を割り当てることができます。しかし、動的配列にすることはできません。 –
@weiZhang:分かりません。私はこれが同じメモリを参照していると言いました。ポインタをC関数に戻すことを止めるものは何もありません。これにより、単にGoのインデックス表記で配列の値にアクセスできます。 – JimB
ありがとう、私は再び試してデバッグします。 –