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.
99
-
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:
97
+
LLGo cannot use anonymous function types directly as field types. To preserve type information, llcppg automatically generates named function types and references them in the field and following this naming convention:
@@ -206,7 +204,6 @@ char matrix[3][4]; // In function parameter becomes **c.Char
206
204
char field[3][4]; // In struct field becomes [3][4]c.Char
207
205
```
208
206
209
-
210
207
#### Name Mapping Rules
211
208
212
209
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 +503,166 @@ linux amd64 `t1_linux_amd64.go` `t2_linux_amd64.go`
506
503
```go
507
504
// +build linux,amd64
508
505
package xxx
509
-
```
506
+
```
507
+
508
+
## Usage
509
+
510
+
```sh
511
+
llcppg [config-file]
512
+
```
513
+
514
+
If `config-file` is not specified, a `llcppg.cfg` file is used in current directory. The configuration file format is as follows:
515
+
516
+
```json
517
+
{
518
+
"name": "inih",
519
+
"cflags": "$(pkg-config --cflags inireader)",
520
+
"include": [
521
+
"INIReader.h",
522
+
"AnotherHeaderFile.h"
523
+
],
524
+
"libs": "$(pkg-config --libs inireader)",
525
+
"trimPrefixes": ["Ini", "INI"],
526
+
"cplusplus":true,
527
+
"deps":["c","github.com/..../third"],
528
+
"mix":false
529
+
}
530
+
```
531
+
532
+
## Process Steps
533
+
534
+
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.
535
+
536
+
1. llcppsymg: Generate symbol table for a C/C++ library
537
+
2. llcppsigfetch: Fetch information of C/C++ symbols
538
+
3. gogensig: Generate a Go package by information of symbols
539
+
540
+
### llcppsymg
541
+
542
+
```sh
543
+
llcppsymg config-file
544
+
llcppsymg - # read config from stdin
545
+
```
546
+
547
+
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:
548
+
549
+
1. Parse dynamic library symbols: Extract exported symbols from libraries using the nm tool
550
+
2. Parse header file declarations: Analyze C/C++ header files using libclang for function declarations
551
+
3. Find intersection: Match library symbols with header declarations and then generate symbol table named `llcppg.symb.json`.
552
+
553
+
#### Symbol Table
554
+
555
+
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:
556
+
557
+
```json
558
+
[
559
+
{
560
+
"mangle": "cJSON_Delete",
561
+
"c++": "cJSON_Delete(cJSON *)",
562
+
"go": "(*CJSON).Delete"
563
+
},
564
+
]
565
+
```
566
+
567
+
* mangle: mangled name of function
568
+
* c++: C/C++ function prototype declaration string
569
+
* go: corresponding Go function or method name, during the process, llcppg will automatically check if the current function can be a method
570
+
1. When go is "-", the function is ignored (not generated)
571
+
2. When go is a valid function name, the function name will be named as the mangle
572
+
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
573
+
574
+
#### Custom Symbol Table generation
575
+
576
+
Specify function mapping behavior in `llcppg.cfg` by config the `symMap` field:
577
+
```json
578
+
{
579
+
"symMap":{
580
+
"mangle":"<goFuncName> | <.goMethodName> | -"
581
+
}
582
+
}
583
+
```
584
+
`mangle` is the symbol name of the function. For the value of `mangle`, you can customize it as:
585
+
1.`goFuncName` - generates a regular function named `goFuncName`
586
+
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)
587
+
3.`-` - completely ignore this function
588
+
589
+
For example, to convert `(*CJSON).PrintUnformatted` from a method to a function, you can use follow config:
590
+
591
+
```json
592
+
{
593
+
"symMap":{
594
+
"cJSON_PrintUnformatted":"PrintUnformatted"
595
+
}
596
+
}
597
+
```
598
+
and the `llcppg.symb.json` will be:
599
+
```json
600
+
[
601
+
{
602
+
"mangle": "cJSON_PrintUnformatted",
603
+
"c++": "cJSON_PrintUnformatted(cJSON *)",
604
+
"go": "PrintUnformatted"
605
+
}
606
+
]
607
+
```
608
+
609
+
### llcppsigfetch
610
+
611
+
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.
612
+
613
+
```sh
614
+
llcppsigfetch config-file
615
+
llcppsigfetch - # read config from stdin
616
+
```
617
+
618
+
* Preprocesses C/C++ header files
619
+
* Creates translation units using libclang and traverses the preprocessed header file to extract ast info.
620
+
621
+
#### Output:
622
+
623
+
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:
624
+
625
+
* File: Contains the AST with decls, includes, and macros.
626
+
* FileMap: Maps file paths to file types, where FileType indicates file classification (interface, implementation, or third-party files)
627
+
628
+
```json
629
+
{
630
+
"File": {
631
+
"decls": [],
632
+
"includes": [],
633
+
"macros": []
634
+
},
635
+
"FileMap": {
636
+
"usr/include/sys/_types/_rsize_t.h": {
637
+
"FileType": 3
638
+
},
639
+
"/opt/homebrew/include/lua/lua.h": {
640
+
"FileType": 1
641
+
},
642
+
"/opt/homebrew/include/lua/luaconf.h": {
643
+
"FileType": 2
644
+
}
645
+
}
646
+
}
647
+
```
648
+
649
+
### gogensig
650
+
651
+
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.
652
+
653
+
```sh
654
+
gogensig pkg-info-file
655
+
gogensig - # read pkg-info-file from stdin
656
+
```
657
+
658
+
#### Function Generation
659
+
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.
660
+
661
+
1. Regular function format: "FunctionName"
662
+
* Generates regular functions, using `//go:linkname` annotation
0 commit comments