2015-02-10 2 views
5

Я использую go-hdf5 для чтения файла hdf5 в golang. Я нахожусь на windows7, используя довольно недавнюю копию mingw и hdf5 1.8.14_x86, и кажется, что попытка использовать любой из предопределенных типов не работает, давайте сосредоточимся, например, на T_NATIVE_UINT64. Я сократил этот вопрос к следующему, который в основном листья идут-hdf5 из проблемы и указывает на то, довольно фундаментальной идет не так:Почему я не могу правильно прочитать константу C из Голанга?

package main 

/* 
#cgo CFLAGS: -IC:/HDF_Group/HDF5/1.8.14_x86/include 
#cgo LDFLAGS: -LC:/HDF_Group/HDF5/1.8.14_x86/bin -lhdf5 -lhdf5_hl 
#include "hdf5.h" 

#include <stdio.h> 

void print_the_value2() { printf("the value of the constant is %d\n", H5T_NATIVE_UINT64); } 
*/ 
import "C" 

func main() { 
    C.print_the_value2() 
} 

Вы, очевидно, нужно иметь hdf5 и указать компилятор на заголовки/DLLs и запуск идут получить, затем выполняя печать это на моем компьютере

the value of the constant is -1962924545 

Запуск вариации выше, в том, как/где константа чтения, будет давать разные ответы на ценности H5T_NATIVE_UINT64. Однако я уверен, что это ничто не является правильным значением и на самом деле попытка использовать тип с возвращенным идентификатором не работает, неудивительно.

Если я пишу и запустить "реальную" программу C, я получаю разные результаты

#include <stdio.h> 
#include "hdf5.h" 

hid_t _go_hdf5_H5T_NATIVE_UINT64() { return H5T_NATIVE_UINT64; } 

int main() 
{ 
    printf("the value of the constant is %d", _go_hdf5_H5T_NATIVE_UINT64()); 
} 

Компиляция с использованием

C:\Temp>gcc -IC:/HDF_Group/HDF5/1.8.14_x86/include -LC:/HDF_Group/HDF5/1.8.14_x86/bin -lhdf5 -lhdf5_hl -o stuff.exe stuff.c 

и бег дает мне

the value of the constant is 50331683 

И что появляется чтобы быть правильным значением, поскольку я могу использовать его непосредственно из моей программы go. Очевидно, я хочу использовать константы вместо этого. Любая идея, почему это может произойти?

Дополнительные информации следующие комментарии ниже:

Я искал определение H5T_NATIVE_UINT64 в заголовках hdf5 увидеть следующую

c:\HDF_Group\HDF5\1.8.14_x86\include>grep H5T_NATIVE_UINT64 * 
H5Tpkg.h:H5_DLLVAR size_t H5T_NATIVE_UINT64_ALIGN_g; 
H5Tpublic.h:#define H5T_NATIVE_UINT64 (H5OPEN H5T_NATIVE_UINT64_g) 
H5Tpublic.h:H5_DLLVAR hid_t H5T_NATIVE_UINT64_g; 

Весь заголовок здесь

http://www.hdfgroup.org/ftp/HDF5/prev-releases/hdf5-1.8.14/src/unpacked/src/H5Tpublic.h

Благодаря!

+0

Можете ли вы показать мне, как определяется константа H5T_NATIVE_UINT64? – fuz

+0

Просматривая заголовки, я получаю этот 'C: \ HDF_Group \ HDF5 \ 1.8.14_x86 \ включают> Grep H5T_NATIVE_UINT64 * H5Tpkg.h: H5_DLLVAR size_t H5T_NATIVE_UINT64_ALIGN_g; H5Tpublic.h: #define H5T_NATIVE_UINT64 (H5OPEN H5T_NATIVE_UINT64_g) H5Tpublic.h: H5_DLLVAR hid_t H5T_NATIVE_UINT64_g; ' – kch

+0

Ваш комментарий трудно читать. Не могли бы вы добавить эту информацию к своему вопросу? Рядом с ним есть кнопка редактирования. Добавьте как можно больше информации, включая все типы и соответствующие макроопределения. – fuz

ответ

0

H5T_NATIVE_UINT64 НЕ является константой, но #define, которая в конечном счете оценивает значение (H5Open(), H5T_NATIVE_UINT64_g), которое cgo не понимает.

Это легко проверить путем включения отладочного вывода на препроцессора ССЗ:

gcc -E -dM your_test_c_file.c | grep H5T_NATIVE_UINT64 

Результат:

#define H5T_NATIVE_UINT64 (H5OPEN H5T_NATIVE_UINT64_g) 

Теперь же для H5OPEN:

gcc -E -dM test_go.c | grep '#define H5OPEN' 

дает:

#define H5OPEN H5open(), 

Прямо сейчас, cgo понимает простую целочисленную константу, такую ​​как #define VALUE 1234, или что-либо, что препроцессор gcc превратится в константу целого. См. Функцию func (p *Package) guessKinds(f *File) в $GOROOT/src/cmd/cgo/gcc.go.

+0

Итак, почему он работает на Linux? Или не так ли? Означает ли это, что использование hdf5 из golang обречено? – kch

+0

cgo не может оценивать не постоянные #define на * любой * платформе. Использование hdf5 из Go не обречено, вам просто нужно найти/написать оболочку Go, которая предоставляет правильный API стиля Go без смешных #defines. Вы также можете попробовать [Swig] (http://www.swig.org/). BTW, определение, которое вы укажете, генерирует вызов func, за которым следует переменная ... Я думаю, значение переменной используется как значение псевдо-выражения, которое должно представлять #define. Что это за API? Вы просмотрели количество предупреждений, сгенерированных при компиляции hdf5 libs? Я не тронул бы его с помощью копья. – wldsvc

+0

OK спасибо за вход! Ну, этот пакет является единственным для go/hdf5. Думаю, я буду придерживаться старых старых CSV-файлов, пока не смогу найти лучший способ. – kch