You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
For cases where a parameter in a function signature is an anonymous function pointer (meaning it does not reference a pre-defined function pointer type), it is mapped to the corresponding Go function type.
For struct fields that are named function pointer types, the field type is replaced with a `c.Pointer` for description.
87
-
88
-
```c
89
-
typedefstruct Stream {
90
-
CallBack cb;
91
-
} Stream;
92
-
```
93
-
```go
94
-
typeStreamstruct {
95
-
Cb c.Pointer
96
-
}
97
-
```
98
-
Due to the characteristics of LLGo, an anonymous function type cannot be directly declared as a Field Type. So to preserve as much information as possible, we need to use a `c.Pointer` to describe the field type.
97
+
Due to the characteristics of LLGo, an anonymous function type cannot be directly declared as a Field Type. So to preserve as much information as possible, we need to use a autogenerated function type and reference it to describe the field type.
99
98
100
-
For anonymous function pointer types, llgo will build a public function type for them and reference it,and ensure that the anonymous type is unique, the naming rule for the corresponding type will be:
99
+
llcppg will build a public function type for them and reference it,and ensure that the anonymous func type is unique, the naming rule for the corresponding type will be:
@@ -206,7 +205,6 @@ char matrix[3][4]; // In function parameter becomes **c.Char
206
205
char field[3][4]; // In struct field becomes [3][4]c.Char
207
206
```
208
207
209
-
210
208
#### Name Mapping Rules
211
209
212
210
The llcppg system converts C/C++ type names to Go-compatible identifiers following specific transformation rules. These rules ensure generated Go code follows Go naming conventions while maintaining clarity and avoiding conflicts.
@@ -506,4 +504,166 @@ linux amd64 `t1_linux_amd64.go` `t2_linux_amd64.go`
506
504
```go
507
505
// +build linux,amd64
508
506
package xxx
509
-
```
507
+
```
508
+
509
+
## Usage
510
+
511
+
```sh
512
+
llcppg [config-file]
513
+
```
514
+
515
+
If `config-file` is not specified, a `llcppg.cfg` file is used in current directory. The configuration file format is as follows:
516
+
517
+
```json
518
+
{
519
+
"name": "inih",
520
+
"cflags": "$(pkg-config --cflags inireader)",
521
+
"include": [
522
+
"INIReader.h",
523
+
"AnotherHeaderFile.h"
524
+
],
525
+
"libs": "$(pkg-config --libs inireader)",
526
+
"trimPrefixes": ["Ini", "INI"],
527
+
"cplusplus":true,
528
+
"deps":["c","github.com/..../third"],
529
+
"mix":false
530
+
}
531
+
```
532
+
533
+
## Process Steps
534
+
535
+
The llcppg tool orchestrates a three-stage pipeline that automatically generates Go bindings for C/C++ libraries by coordinating symbol table generation, signature extraction, and Go code generation components.
536
+
537
+
1. llcppsymg: Generate symbol table for a C/C++ library
538
+
2. llcppsigfetch: Fetch information of C/C++ symbols
539
+
3. gogensig: Generate a Go package by information of symbols
540
+
541
+
### llcppsymg
542
+
543
+
```sh
544
+
llcppsymg config-file
545
+
llcppsymg - # read config from stdin
546
+
```
547
+
548
+
llcppsymg is the symbol table generator in the llcppg toolchain, responsible for analyzing C/C++ dynamic libraries and header files to generate symbol mapping tables. Its main functions are:
549
+
550
+
1. Parse dynamic library symbols: Extract exported symbols from libraries using the nm tool
551
+
2. Parse header file declarations: Analyze C/C++ header files using libclang for function declarations
552
+
3. Find intersection: Match library symbols with header declarations and then generate symbol table named `llcppg.symb.json`.
553
+
554
+
#### Symbol Table
555
+
556
+
This symbol table determines whether the function appears in the generated Go code、its actual name and if it is a method. Its file format is as follows:
557
+
558
+
```json
559
+
[
560
+
{
561
+
"mangle": "cJSON_Delete",
562
+
"c++": "cJSON_Delete(cJSON *)",
563
+
"go": "(*CJSON).Delete"
564
+
},
565
+
]
566
+
```
567
+
568
+
* mangle: mangled name of function
569
+
* c++: C/C++ function prototype declaration string
570
+
* go: corresponding Go function or method name, during the process, llcppg will automatically check if the current function can be a method
571
+
1. When go is "-", the function is ignored (not generated)
572
+
2. When go is a valid function name, the function name will be named as the mangle
573
+
3. When go is `(*Type).MethodName` or `Type.MethodName`, the function will be generated as a method with Receiver as Type/*Type, and Name as MethodName
574
+
575
+
#### Custom Symbol Table generation
576
+
577
+
Specify function mapping behavior in `llcppg.cfg` by config the `symMap` field:
578
+
```json
579
+
{
580
+
"symMap":{
581
+
"mangle":"<goFuncName> | <.goMethodName> | -"
582
+
}
583
+
}
584
+
```
585
+
`mangle` is the symbol name of the function. For the value of `mangle`, you can customize it as:
586
+
1.`goFuncName` - generates a regular function named `goFuncName`
587
+
2.`.goMethodName` - generates a method named `goMethodName` (if it doesn't meet the rules for generating a method, it will be generated as a regular function)
588
+
3.`-` - completely ignore this function
589
+
590
+
For example, to convert `(*CJSON).PrintUnformatted` from a method to a function, you can use follow config:
591
+
592
+
```json
593
+
{
594
+
"symMap":{
595
+
"cJSON_PrintUnformatted":"PrintUnformatted"
596
+
}
597
+
}
598
+
```
599
+
and the `llcppg.symb.json` will be:
600
+
```json
601
+
[
602
+
{
603
+
"mangle": "cJSON_PrintUnformatted",
604
+
"c++": "cJSON_PrintUnformatted(cJSON *)",
605
+
"go": "PrintUnformatted"
606
+
}
607
+
]
608
+
```
609
+
610
+
### llcppsigfetch
611
+
612
+
llcppsigfetch is a tool that extracts type information and function signatures from C/C++ header files. It uses Clang & Libclang to parse C/C++ header files and outputs a JSON-formatted package information structure.
613
+
614
+
```sh
615
+
llcppsigfetch config-file
616
+
llcppsigfetch - # read config from stdin
617
+
```
618
+
619
+
* Preprocesses C/C++ header files
620
+
* Creates translation units using libclang and traverses the preprocessed header file to extract ast info.
621
+
622
+
#### Output:
623
+
624
+
The output is a `pkg-info` structure that contains comprehensive package information needed for Go code generation. This `pkg-info` consists of two main components:
625
+
626
+
* File: Contains the AST with decls, includes, and macros.
627
+
* FileMap: Maps file paths to file types, where FileType indicates file classification (interface, implementation, or third-party files)
628
+
629
+
```json
630
+
{
631
+
"File": {
632
+
"decls": [],
633
+
"includes": [],
634
+
"macros": []
635
+
},
636
+
"FileMap": {
637
+
"usr/include/sys/_types/_rsize_t.h": {
638
+
"FileType": 3
639
+
},
640
+
"/opt/homebrew/include/lua/lua.h": {
641
+
"FileType": 1
642
+
},
643
+
"/opt/homebrew/include/lua/luaconf.h": {
644
+
"FileType": 2
645
+
}
646
+
}
647
+
}
648
+
```
649
+
650
+
### gogensig
651
+
652
+
gogensig is the final component in the pipeline, responsible for converting C/C++ type declarations and function signatures into Go code. It reads the `pkg-info` structure generated by llcppsigfetch.
653
+
654
+
```sh
655
+
gogensig pkg-info-file
656
+
gogensig - # read pkg-info-file from stdin
657
+
```
658
+
659
+
#### Function Generation
660
+
During execution, gogensig only generates functions whose corresponding mangle exists in llcppg.symb.json, determining whether to generate functions/methods with specified Go names by parsing the go field corresponding to the mangle.
661
+
662
+
1. Regular function format: "FunctionName"
663
+
* Generates regular functions, using `//go:linkname` annotation
0 commit comments