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