c-for-go
c-for-go copied to clipboard
Wrong accessors for C-structs in cgo_helpers.go
I am building a wrapper for cimgui with c-for-go and I cannot get it to build the generated code because the accessors to c-structs are wrong.
One of many (nearly 800) examples from the generated code:
const sizeOfImcolorValue = unsafe.Sizeof([1]C.ImColor{})
If it is changed to C.struct_ImColor{}
it works. I cannot find information about that in the documentation. After Looking at some of the example projects I tried to add StructAccessors: true
to generator options, but it did not change anything.
I tried to use c-for-go with one of the provided examples and It generates the correct .struct_
accessors.
I don't know what I am doing wrong. My yml configuration only contains accept, replace, and transform rules as well as some pointer tips.
Hi!
ImColor
is a valid typedef https://github.com/cimgui/cimgui/blob/master/cimgui.h#L61
Why C.ImColor
doesnt' work for you?
You can try to disable those typedefs in the original .h by CIMGUI_DEFINE_ENUMS_AND_STRUCTS
, maybe that'd help. But seriously the way it works for you should be ok.. Could you share your .yml with me?
Of course. Here is my yml. Or in case it is easier for you, you can find the whole wrapper project here: https://github.com/nazzrim/imgui-go
You can "ignore" the FlagGroups since they are the result of some trial and error and do not change anything.
GENERATOR:
PackageName: imgui
PackageDescription: "Package imgui provides Go bindings for cimgui which is a C-wrapper for Dear ImGui by ocornut"
PackageLicense: "THE AUTOGENERATED LICENSE. ALL THE RIGHTS ARE RESERVED BY ROBOTS."
Includes: ["../cimgui/cimgui.h"]
Options:
SafeStrings: true
StructAccessors: true
FlagGroups:
- {name: "LDFLAGS", flags: [-lpd]}
- {name: "CXXFLAGS", flags: [-std=c++11]}
PARSER:
IncludePaths:
SourcesPaths:
- cimgui/cimgui.h
Defines:
CIMGUI_DEFINE_ENUMS_AND_STRUCTS: 1
__builtin_va_start: {}
__builtin_va_end: {}
TRANSLATOR:
ConstRules:
defines: eval
enum: expand
Rules:
global:
- {transform: lower}
- {action: accept, from: "^ig"}
- {action: accept, from: "^Im"}
- {action: replace, from: "^ig"}
- {action: replace, from: "^ImGui"}
- {action: replace, from: "^ImVec2_ImVec2", to: "ImVec2"}
- {action: replace, from: "^ImVec4_ImVec4", to: "ImVec4"}
- {action: replace, from: "^ImGuiStoragePair_ImGuiStoragePair", to: "ImGuiStoragePair"}
- {transform: export}
const:
- {action: accept, from: "^Im"}
- {transform: export}
type:
- {action: accept, from: "^Im"}
- {transform: export}
private:
- {transform: unexport}
post-global:
- {action: replace, from: _$}
- {load: snakecase}
PtrTips:
struct:
function:
- {target: "^ImVec2_destroy$", tips: [ref]}
- {target: "^ImVec4_destroy$", tips: [ref]}
- {target: "^igCreateContext$", tips: [ref]}
- {target: "^igDestroyContext$", tips: [ref]}
- {target: "^igSetCurrentContext$", tips: [ref]}
- {target: "^igShowDemoWindow$", tips: [ref]}
- {target: "^igShowAboutWindow$", tips: [ref]}
- {target: "^igShowMetricsWindow$", tips: [ref]}
- {target: "^igShowStyleEditor$", tips: [ref]}
- {target: "^igStyleColorsDark$", tips: [ref]}
- {target: "^igStyleColorsClassic$", tips: [ref]}
- {target: "^igStyleColorsLight$", tips: [ref]}
- {target: "^igBegin$", tips: [0,ref,0]}
- {target: "^igPushFont$", tips: [ref]}
- {target: "^igCheckbox$", tips: [0,ref]}
- {target: "^igCheckboxFlags$", tips: [0,ref,0]}
- {target: "^igRadioButtonIntPtr$", tips: [0,ref,0]}
- {target: "^igCombo$", tips: [0,ref,0,0,0]}
- {target: "^igComboStr$", tips: [0,ref,0,0]}
- {target: "^igComboFnPtr$", tips: [0,ref,0,0,0,0]}
- {target: "^igDragFloat$", tips: [0,ref,0,0,0,0,0]}
- {target: "^igDragFloatRange2$", tips: [0,ref,ref,0,0,0,0,0,0]}
- {target: "^igDragInt$", tips: [0,ref,0,0,0,0]}
- {target: "^igDragIntRange2$", tips: [0,ref,ref,0,0,0,0,0]}
- {target: "^igSliderFloat$", tips: [0,ref,0,0,0,0]}
- {target: "^igSliderAngle$", tips: [0,ref,0,0,0]}
- {target: "^igSliderInt$", tips: [0,ref,0,0,0]}
- {target: "^igVSliderFloat$", tips: [0,0,ref,0,0,0,0]}
- {target: "^igVSliderInt$", tips: [0,0,ref,0,0,0]}
- {target: "^igInputFloat$", tips: [0,ref,0,0,0,0]}
- {target: "^igInputInt$", tips: [0,ref,0,0,0]}
- {target: "^igInputDouble$", tips: [0,ref,0,0,0,0]}
- {target: "^igColorPicker4$", tips: [0,0,0,ref]}
- {target: "^igCollapsingHeaderBoolPtr$", tips: [0,ref,0]}
- {target: "^igSelectableBoolPtr$", tips: [0,ref,0,0]}
- {target: "^igListBoxStr_arr$", tips: [0,ref,0,0,0]}
- {target: "^igListBoxFnPtr$", tips: [0,ref,0,0,0,0]}
- {target: "^igMenuItemBoolPtr$", tips: [0,0,ref,0]}
- {target: "^igBeginPopupModal$", tips: [0,ref,0]}
- {target: "^igBeginTabItem$", tips: [0,ref,0]}
- {target: "^igShowDemoWindow$", tips: [ref]}
- {target: "^igCalcListClipping$", tips: [0,0,ref,ref]}
- {target: "^igIsMousePosValid$", tips: [ref]}
- {target: "^igSaveIniSettingsToMemory$", tips: [ref]}
- {target: "^ImGuiStyle_destroy$", tips: [ref]}
- {target: "^ImGuiStyle_ScaleAllSizes$", tips: [ref,0]}
- {target: "^ImGuiIO_AddInputCharacter$", tips: [ref,0]}
- {target: "^ImGuiIO_AddInputCharactersUTF8$", tips: [ref,0]}
- {target: "^ImGuiIO_ClearInputCharacters$", tips: [ref]}
- {target: "^ImGuiIO_destroy$", tips: [ref]}
- {target: "^ImGuiInputTextCallbackData_destroy$", tips: [ref]}
- {target: "^ImGuiInputTextCallbackData_DeleteChars$", tips: [ref,0,0]}
- {target: "^ImGuiInputTextCallbackData_InsertChars$", tips: [ref,0,0]}
- {target: "^ImGuiInputTextCallbackData_HasSelection$", tips: [ref]}
- {target: "^ImGuiPayload_destroy$", tips: [ref]}
- {target: "^ImGuiPayload_Clear$", tips: [ref]}
- {target: "^ImGuiPayload_IsDataType$", tips: [ref,0]}
- {target: "^ImGuiPayload_IsPreview$", tips: [ref]}
- {target: "^ImGuiPayload_IsDelivery$", tips: [ref]}
- {target: "^ImGuiOnceUponAFrame_destroy$", tips: [ref]}
- {target: "^ImGuiTextFilter_destroy$", tips: [ref]}
- {target: "^ImGuiTextFilter_Draw$", tips: [ref,0,0]}
- {target: "^ImGuiTextFilter_PassFilter$", tips: [ref,0,0]}
- {target: "^ImGuiTextFilter_Build$", tips: [ref]}
- {target: "^ImGuiTextFilter_Clear$", tips: [ref]}
- {target: "^ImGuiTextFilter_IsActive$", tips: [ref]}
- {target: "^ImGuiTextRange_destroy$", tips: [ref]}
- {target: "^ImGuiTextRange_empty$", tips: [ref]}
- {target: "^ImGuiTextRange_split$", tips: [ref,0,0]}
- {target: "^ImGuiTextBuffer_destroy$", tips: [ref]}
- {target: "^ImGuiTextBuffer_begin$", tips: [ref]}
- {target: "^ImGuiTextBuffer_end$", tips: [ref]}
- {target: "^ImGuiTextBuffer_size$", tips: [ref]}
- {target: "^ImGuiTextBuffer_empty$", tips: [ref]}
- {target: "^ImGuiTextBuffer_clear$", tips: [ref]}
- {target: "^ImGuiTextBuffer_reserve$", tips: [ref,0]}
- {target: "^ImGuiTextBuffer_c_str$", tips: [ref]}
- {target: "^ImGuiTextBuffer_append$", tips: [ref,0,0]}
- {target: "^ImGuiTextBuffer_appendfv$", tips: [ref,0,0]}
- {target: "^ImGuiStoragePair_destroy$", tips: [ref]}
- {target: "^ImGuiStoragePair_ImGuiStoragePairPtr$", tips: [0,ref]}
- {target: "^ImGuiStorage_Clear$", tips: [ref]}
- {target: "^ImGuiStorage_Get", tips: [ref,0,0]}
- {target: "^ImGuiStorage_Set", tips: [ref,0,0]}
- {target: "^ImGuiStorage_BuildSortByKey$", tips: [ref]}
- {target: "^ImGuiListClipper_", tips: [ref]}
- {target: "^ImColor_destroy$", tips: [ref]}
- {target: "^ImColor_SetHSV$", tips: [ref,0,0,0,0]}
- {target: "^ImColor_HSV$", tips: [ref,0,0,0,0]}
- {target: "^ImDrawListSplitter_", tips: [ref,ref]}
- {target: "^ImDrawList_", tips: [ref,ref]}
- {target: "^ImDrawList_AddTextFontPtr$", tips: [ref,ref,0,0,0,0,0,0,ref]}
- {target: "^ImDrawData_", tips: [ref]}
- {target: "^ImFontConfig_", tips: [ref]}
- {target: "^ImFontGlyphRangesBuilder_", tips: [ref]}
- {target: "^ImFontGlyphRangesBuilder_AddRanges$", tips: [ref,ref]}
- {target: "^ImFontGlyphRangesBuilder_BuildRanges$", tips: [ref,ref]}
- {target: "^ImFontAtlasCustomRect_", tips: [ref]}
- {target: "^ImFontAtlas_", tips: [ref,ref]}
- {target: "^ImFontAtlas_AddFontFromFileTTF$", tips: [ref,0,0,ref,ref]}
- {target: "^ImFontAtlas_AddFontFromMemoryTTF$", tips: [ref,0,0,0,ref,ref]}
- {target: "^ImFontAtlas_AddFontFromMemoryCompressedTTF$", tips: [ref,0,0,0,ref,ref]}
- {target: "^ImFontAtlas_AddFontFromMemoryCompressedBase85TTF$", tips: [ref,0,0,ref,ref]}
- {target: "^ImFontAtlas_GetTexDataAs", tips: [ref,sref,ref,ref,ref]}
- {target: "^ImFontAtlas_CalcCustomRectUV$", tips: [ref,ref,ref,ref]}
- {target: "^ImFontAtlas_GetMouseCursorTexData$", tips: [ref,0,ref,ref,0,0]}
- {target: "^ImFont_", tips: [ref]}
- {target: "^ImFont_Render", tips: [ref,ref]}
- {target: "^igGetWindow", tips: [ref]}
- {target: "^igGetContent", tips: [ref]}
- {target: "^igGetFont", tips: [ref]}
- {target: "^igGetCursor", tips: [ref]}
- {target: "^igGetItem", tips: [ref]}
- {target: "^igCalcTextSize_nonUDT$", tips: [ref,0,0,0,0]}
- {target: "^igColorConvertU32ToFloat4_nonUDT$", tips: [ref,0]}
- {target: "^igGetMouse", tips: [ref]}
- {target: "^ImColor_HSV_nonUDT$", tips: [ref,ref,0,0,0,0]}
- {target: "^ImColor_HSV_nonUDT2$", tips: [ref,0,0,0,0]}
- {target: "^ImDrawList_GetClipRect", tips: [ref,ref]}
- {target: "^ImFont_CalcTextSizeA_nonUDT$", tips: [ref,ref,0,0,0,0,0,0]}
- {target: "^ImFont_CalcTextSizeA_nonUDT2$", tips: [ref,0,0,0,0,0,0]}
- {target: "^ImGuiTextBuffer_appendf$", tips: [ref,0]}
- {target: "^igColorConvert", tips: [0,0,0,ref,ref,ref]}
- {target: "^ImVector_ImWchar_", tips: [ref]}
TypeTips:
function:
MemTips:
By the way: If I undef CIMGUI_DEFINE_ENUMS_AND_STRUCTS
c-for-go does abort its execution with errors because of the missing definitions. I reported this in #80
I guess I am at something here:
The following part of my yml does not propagate to the generated .go file, it is only used during the generation (I guess):
Defines:
CIMGUI_DEFINE_ENUMS_AND_STRUCTS: 1
This is the header of the main go file generated with c-for-go
/*
#include "../cimgui/cimgui.h"
#include <stdlib.h>
#include "cgo_helpers.h"
*/
import "C"
import (
"runtime"
"unsafe"
)
If I manually delete all the corresponding directives from cimgui.h it compiles with a warning (which I am ignoring right now).
So the question is: What entries are required to embedd #define directives into the generated .go file?
So if I add #define CIMGUI_DEFINE_ENUMS_AND_STRUCTS 1
to imgui.go and cgo_helpers.go manually the errors disappear.
~~I assume that adding it to all generated files would be a more general and safe solution (?).~~
Edit: I needed to add it to all generated go files which include C and the cgo_helper.h file.
But then the compilation gives me the following error:
go build ./... # github.com/nazzrim/imgui-go/imgui
imgui\imgui.go:5359:2: unexpected type: ...
Which references this line:
C.ImGuiTextBuffer_appendf(cbuffer, cfmt)
And the ImGuiTextBuffer_appendf
function has the following signature:
CIMGUI_API void ImGuiTextBuffer_appendf(struct ImGuiTextBuffer *buffer, const char *fmt, ...);
I tried to ignore this single function but it seems that all functions with ... parameters are problematic.
Therefore I ignore all variadic functions. But then I get errors like.
AppData\Local\Temp\go-build275703602\b001\_x004.o: In function `_cgo_e0dda29f671c_Cfunc_igValueUint':
/tmp/go-build/cgo-gcc-prolog:10084: undefined reference to `igValueUint'
Okay I am able to get to the point I described in my last post without manual changes to the generated files by using the following configuration:
GENERATOR:
PackageName: imgui
PackageDescription: "Package imgui provides Go bindings for cimgui which is a C-wrapper for Dear ImGui by ocornut"
PackageLicense: "THE AUTOGENERATED LICENSE. ALL THE RIGHTS ARE RESERVED BY ROBOTS."
Includes: ["cimgui.h"]
Options:
SafeStrings: true
StructAccessors: true
FlagGroups:
- {name: CFLAGS, flags: [-DCIMGUI_DEFINE_ENUMS_AND_STRUCTS,"-I${SRCDIR}/cimgui"]}
PARSER:
IncludePaths:
SourcesPaths:
- cimgui/cimgui.h
Defines:
CIMGUI_DEFINE_ENUMS_AND_STRUCTS: 1
__builtin_va_start: {}
__builtin_va_end: {}
But during the compilation I get undefined references for all functions in cimgui.h.
AppData\Local\Temp\go-build240611998\b001\_x004.o: In function `_cgo_f5785d863652_Cfunc_igSpacing':
/tmp/go-build/cgo-gcc-prolog:9670: undefined reference to `igSpacing'
Okay, the errors I mentioned in my last post were caused by my messed up linker flags, sorry for that.
Hopefully this journey will help someone else who is new to c-for-go ;D.
Now I am running into the same issue as #60 and right now I don't know how I should provide the required typedefs since I need to make the structs in the cimgui header use it.
(To be more precise: struct IO has three function pointer fields and NewRef as well as PassRef are not generated for these fields)
Apple decided that I don't need /usr/include
on my machine, so I'm currently disarmed :)
Will figure out how to get that back, but I hope you'll find the way through! 🙏
I hopefully will find a solution and maybe my documentation here can help others with similar problems :).
Do you have an example of the solution you recommend in #60? Because my current problem is the following:
- I cannot redefine the typedef for ImGuiIO since C doesn't allow that
- I can provide my own ImGuiIO when I use a "patch" header like this:
#ifndef PATCH_H
#define PATCH_H
#define ImGuiIO ImGuiIO_orig
#include "cimgui/cimgui.h"
#undef ImGuiIO
typedef const char* (*get_clipboard_fn)(void* user_data);
typedef void (*set_clipboard_fn)(void* user_data, const char* text);
typedef void (*set_input_screen_fn)(int x, int y);
typedef struct _ImGuiIO_
{
...
} ImGuiIO;
#endif
- But there are two issues with that:
- All functions returning/accepting ImGuiIO are redefined, too. Therefore the patch would get bigger since I need to include all these functions which may require a lot of maintainance on version changes. So this is at least undesirable.
- I am currently not able to configure c-for-go to ignore ImGuiIO_orig and only use my ImGuiIO
@nazzrim did you ever figure out what to do about #60? I imagine there is no workaround for larger libraries where there are a multitude of function pointers?
@imle No, I did not find a solution for #60 and I did not find any workarounds, sorry.