diff --git a/README.md b/README.md
index b9fc9d9..7cd0f6c 100644
--- a/README.md
+++ b/README.md
@@ -101,17 +101,20 @@ This generates:
### Using the Library from Python
```python
-from ctypes import cdll, c_char_p
+from ctypes import cdll, c_char_p, POINTER, c_int
lib = cdll.LoadLibrary('./build/libschema.so')
-lib.Convert.argtypes = [c_char_p]
+lib.Convert.argtypes = [c_char_p, POINTER(c_char_p), c_int]
lib.Convert.restype = c_char_p
-result = lib.Convert(b'...')
+# Convert HTML with optional elements to strip
+elements_to_strip = []
+arr = (c_char_p * len(elements_to_strip))(*[s.encode('utf-8') for s in elements_to_strip])
+result = lib.Convert(b'...', arr, len(elements_to_strip))
print(result.decode()) # Header stripped, main content preserved
```
-See `examples/test_ffi.py` for a complete working example.
+See `ffi_tests/python/main.py` for a complete working example.
### Automated Releases
diff --git a/cmd/libschema/main.go b/cmd/libschema/main.go
index 71b173b..9dc9df3 100644
--- a/cmd/libschema/main.go
+++ b/cmd/libschema/main.go
@@ -11,20 +11,41 @@ import (
)
//export Convert
-func Convert(htmlInput *C.char, stripNav C.int, stripAside C.int, stripScript C.int) *C.char {
+// Convert processes HTML with optional element stripping configuration.
+//
+// IMPORTANT: The function signature uses **C.char and C.int instead of []*C.char because
+// Go slices cannot be properly passed across CGO/FFI boundaries. Go slices require a
+// slice header (pointer, length, capacity), but when called from Python/Node.js FFI,
+// the caller can only pass a C array pointer. Using a Go slice parameter causes a nil
+// pointer dereference because the slice header is not properly initialized.
+//
+// The correct pattern for passing arrays through CGO is to pass the array pointer
+// (as **C.char) and its length (as C.int) separately, then use unsafe.Slice to convert
+// to a Go slice inside the function.
+func Convert(htmlInput *C.char, elementsToStrip **C.char, elementsLen C.int) *C.char {
if htmlInput == nil {
return C.CString("")
}
// Convert C string to Go string
goHTML := C.GoString(htmlInput)
+ var goElementsToStrip []string
+
+ // Convert C array to Go slice using pointer arithmetic
+ if elementsToStrip != nil && elementsLen > 0 {
+ // Create a slice from the C array
+ cArray := unsafe.Slice(elementsToStrip, elementsLen)
+ for _, cstr := range cArray {
+ if cstr != nil {
+ goElementsToStrip = append(goElementsToStrip, C.GoString(cstr))
+ }
+ }
+ }
// Use the converter package to process HTML with options
// Convert C ints to Go bools
stripConfig := converter.StripConfig{
- StripNav: stripNav != 0,
- StripAside: stripAside != 0,
- StripScript: stripScript != 0,
+ ElementsToStrip: goElementsToStrip,
}
processed, err := converter.ProcessHTML([]byte(goHTML), stripConfig)
if err != nil {
diff --git a/ffi_tests/nodejs/main.js b/ffi_tests/nodejs/main.js
index 70f58da..8e222d8 100644
--- a/ffi_tests/nodejs/main.js
+++ b/ffi_tests/nodejs/main.js
@@ -4,7 +4,8 @@ const koffi = require('koffi')
const lib = koffi.load('./build/libschema.so')
// Define function signatures - using char* for auto string conversion
-const Convert = lib.func('char* Convert(char* htmlInput, int stripNav, int stripAside, int stripScript)')
+// Second param is char** (array of strings), third is int (array length)
+const Convert = lib.func('char* Convert(char* htmlInput, char** elementsToStrip, int elementsLen)')
// Note: Not using Free() due to koffi memory management complexity
// In production, you'd need a proper memory management strategy
@@ -25,8 +26,9 @@ console.log('Testing Convert()...\n')
console.log('Input HTML:')
console.log(htmlInput)
-// Call with all options enabled (strip nav, aside, script)
-const result = Convert(htmlInput, 1, 1, 1)
+// Call with empty array (use defaults)
+const elementsToStrip = []
+const result = Convert(htmlInput, elementsToStrip, elementsToStrip.length)
console.log('\nOutput HTML:')
console.log(result)
diff --git a/ffi_tests/python/main.py b/ffi_tests/python/main.py
index 124faaa..3c50e92 100644
--- a/ffi_tests/python/main.py
+++ b/ffi_tests/python/main.py
@@ -3,7 +3,7 @@
Test script to verify the CGO library works via Python FFI
"""
-from ctypes import cdll, c_char_p, c_bool
+from ctypes import cdll, c_char_p, POINTER
import os
# Load the shared library
@@ -11,7 +11,8 @@
lib = cdll.LoadLibrary(lib_path)
# Set up function signatures
-lib.Convert.argtypes = [c_char_p, c_bool, c_bool, c_bool]
+from ctypes import c_int
+lib.Convert.argtypes = [c_char_p, POINTER(c_char_p), c_int]
lib.Convert.restype = c_char_p
# Test HTML
@@ -27,7 +28,9 @@