feat(loader): make Load idempotent and expose TA-Lib version API

- guard library initialization with sync.Once to avoid duplicate registrations
- refactor loading logic into internalLoad()
- register TA_GetVersionString and expose Version()
- document Version() usage and API behavior in README
This commit is contained in:
2026-07-28 12:25:24 +09:00
parent fc504d0c01
commit b3ad421c76
2 changed files with 30 additions and 1 deletions
+4 -1
View File
@@ -48,7 +48,7 @@ This package does **not** bundle TA-Lib itself. You must install the native libr
## How library loading works
Call `talib.Load()` once before using any indicator function. The loader looks for the platform-specific library name:
Call `talib.Load()` once before using any indicator function. After loading, you can call `talib.Version()` to read the native TA-Lib version string. The loader looks for the platform-specific library name:
- macOS: `libta-lib.dylib`
- Linux: `libta-lib.so`
@@ -103,6 +103,8 @@ func main() {
log.Fatal(err)
}
fmt.Println("TA-Lib version:", talib.Version())
var series []float64
for i := 0; i < 100; i++ {
series = append(series, math.Sin(float64(i)/7)*4.5+math.Cos(float64(i)/19)*1.75)
@@ -122,6 +124,7 @@ func main() {
## API notes
- Indicator functions return `nil` when the underlying TA-Lib call fails.
- `Version()` returns the TA-Lib version string exposed by `TA_GetVersionString` (call after `Load()`).
- Native TA-Lib functions are exposed with Go-style exported names such as `Add`, `Div`, `Max`, and `Sum`.
- Functions accepting a moving-average type use the `MAType` constant (`MA_SMA`, `MA_EMA`, `MA_WMA`, `MA_DEMA`, `MA_TEMA`, `MA_TRIMA`, `MA_KAMA`, `MA_MAMA`, `MA_T3`).
- Functions returning multiple outputs (e.g. `Aroon`, `MACD`, `Stoch`) return multiple slices; all are `nil` on failure.
+26
View File
@@ -1,16 +1,40 @@
package talib
import "C"
import (
"fmt"
"log/slog"
"os"
"path/filepath"
"runtime"
"sync"
"github.com/ebitengine/purego"
)
var (
internalVersion func() string
once sync.Once
)
func Version() string {
return internalVersion()
}
func Load() (uintptr, error) {
var (
ptr uintptr
err error
)
once.Do(func() {
ptr, err = internalLoad()
})
return ptr, err
}
func internalLoad() (uintptr, error) {
var (
path string
ptr uintptr
@@ -26,6 +50,8 @@ func Load() (uintptr, error) {
return 0, err
}
purego.RegisterLibFunc(&internalVersion, ptr, "TA_GetVersionString")
// Register the functions we need from the TA-Lib library
purego.RegisterLibFunc(&ht_dcperiod, ptr, "TA_HT_DCPERIOD")
purego.RegisterLibFunc(&ht_dcphase, ptr, "TA_HT_DCPHASE")