doc/c:fix incorrect usage in construtors

This commit is contained in:
luoliwoshang
2024-07-31 15:13:30 +08:00
parent 4fdfafa17f
commit a4e9233231

View File

@@ -27,7 +27,7 @@ int ini_parse(const char* filename, ini_handler handler, void* user);
3. Create the corresponding Go file 3. Create the corresponding Go file
```c ```bash
inih/ inih/
├── _demo ├── _demo
├── inih_demo ├── inih_demo
@@ -300,50 +300,39 @@ func ParseError() c.Int
- Constructor is explicitly declared in the class (can find the corresponding symbol in the dynamic library): - Constructor is explicitly declared in the class (can find the corresponding symbol in the dynamic library):
Bind to the `InitFromBuffer` method of the struct and call it in the `NewReaderFile` function to initialize the class and return the class for Go to use. ```cpp
class INIReader {
public:
// Construct INIReader and parse given filename.
INI_API explicit INIReader(const std::string &filename);
}
```
Bind to the `InitFromFile` method of the struct and call it in the `NewReaderFile` function to initialize the class and return the class for Go to use.
The following long string starting with `_ZN9INI` is the corresponding function prototype in the symbol table for `INIReader(const std::string &filename)`
```go ```go
// llgo:link (*Reader).InitFromFile C._ZN9INIReaderC1ERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE
func (r *Reader) InitFromFile(fileName *std.String) {}
// NewReaderFile creates a new INIReader instance. // NewReaderFile creates a new INIReader instance.
func NewReaderFile(fileName *std.String) (ret Reader) { func NewReaderFile(fileName *std.String) (ret Reader) {
ret.InitFromFile(fileName) ret.InitFromFile(fileName)
return return
} }
/*
class INIReader
{
public:
explicit INIReader(const char *buffer, size_t buffer_size);
}
*/
// llgo:link (*Reader).InitFromBuffer C._ZN9INIReaderC1EPKcm
func (r *Reader) InitFromBuffer(buffer *c.Char, bufferSize uintptr) {}
``` ```
- Constructor is not explicitly declared in the class (cannot find the corresponding symbol in the dynamic library) - Constructor is not explicitly declared in the class (cannot find the corresponding symbol in the dynamic library)
If the destructor is not explicitly declared in the source code, the compiler will automatically generate a default destructor. Use `extern "C"` to wrap it in cppWrap.cpp: In typical implementations of the inih library, directly invoking implicit constructors to instantiate reader objects is not recommended. For detailed examples of how bindings effectively handle non-exported symbols, please refer to the [Templates and Inlines](#templates-and-inlines) section.
```c
extern "C" void INIReaderInit(INIReader* r)
{
r->INIReader();
}
```
Link in Go:
```go
// llgo:link (*Reader).INIReaderInit C.INIReaderInit
func (r *Reader) INIReaderInit() {}
```
- Destructor - Destructor
Similar to constructors, destructors are typically hidden, so they also need to be wrapped. The wrapping method for destructors differs from that of constructors as follows: Destructors are typically not directly accessible in the dynamic library, so they need to be wrapped. The wrapping method for destructors differs from that of constructors as follows:
In the C++ wrapper file (e.g., cppWrap.cpp): In the C++ wrapper file (e.g., cppWrap.cpp):
```c ```cpp
void INIReaderDispose(INIReader* r) { extern "C" {
r->~INIReader(); void INIReaderDispose(INIReader* r) {
} r->~INIReader();
}
} // extern "C"
``` ```
This wrapper function explicitly calls the object's destructor. By using extern "C", we ensure that this function can be called by C code, allowing Go to link to it. This wrapper function explicitly calls the object's destructor. By using extern "C", we ensure that this function can be called by C code, allowing Go to link to it.
In the Go file: In the Go file:
@@ -376,7 +365,7 @@ func ParseError() c.Int
Templates or inlines do not generate symbols in dynamic libraries (dylib) (default constructors and destructors). To ensure that you can use C style symbols to link template or inline functions, create a C++ file and wrap it with `extern "C"`, then bind the functions directly in Go. Templates or inlines do not generate symbols in dynamic libraries (dylib) (default constructors and destructors). To ensure that you can use C style symbols to link template or inline functions, create a C++ file and wrap it with `extern "C"`, then bind the functions directly in Go.
```c ```cpp
// Using std::string as an example, not needed for migrating inih // Using std::string as an example, not needed for migrating inih
extern "C" void stdStringInitFromCStrLen(std::string* s, const char* cstr, size_t len) { extern "C" void stdStringInitFromCStrLen(std::string* s, const char* cstr, size_t len) {
new(s) std::string(cstr, len); new(s) std::string(cstr, len);