Возможно, я что-то здесь не так понял, но когда я просто игнорирую ошибку, которую мне выдает Windows, и продолжает работать, кажется, все работает нормально.
Например, если я запускаю это:
package main
import (
"errors"
"fmt"
"syscall"
"unsafe"
)
var (
chakraCore, _ = syscall.LoadLibrary("ChakraCore.dll")
jsCreateRuntime, _ = syscall.GetProcAddress(chakraCore, "JsCreateRuntime")
jsCreateContext, _ = syscall.GetProcAddress(chakraCore, "JsCreateContext")
jsSetCurrentContext, _ = syscall.GetProcAddress(chakraCore, "JsSetCurrentContext")
jsRunScript, _ = syscall.GetProcAddress(chakraCore, "JsRunScript")
jsConvertValueToString, _ = syscall.GetProcAddress(chakraCore, "JsConvertValueToString")
jsStringToPointer, _ = syscall.GetProcAddress(chakraCore, "JsStringToPointer")
)
const (
JsNoError = 0
JsErrorInvalidArgument = 0x10001
JsErrorNullArgument = 0x10002
JsErrorScriptCompile = 0x30002
)
const (
JsRuntimeAttributeNone = 0x00000000
)
var jsExample = `
(()=>{
return 'Hello world!';}
)()
`
func main() {
var runtime unsafe.Pointer
var context unsafe.Pointer
var jsResult unsafe.Pointer
var resultJSString unsafe.Pointer
{
const functionName = "JsCreateRuntime"
ret, _, err := syscall.Syscall(
uintptr(jsCreateRuntime),
3,
uintptr(JsRuntimeAttributeNone),
uintptr(0),
uintptr(unsafe.Pointer(&runtime)),
)
// NOTE: Skip this error as it seems to be a false positive
//if err != 0 {
// panic(fmt.Sprintf("%s invalid DLL call: %v", functionName, err))
//}
if err := getJSError(ret); err != nil {
panic(fmt.Sprintf("%s failed: %s", functionName, err))
}
if runtime == nil {
panic("Runtime should not be 0. I think.")
}
fmt.Print(fmt.Sprintf("%s: runtime: %v | error code: %v | dll call error: %v\n", functionName, runtime, ret, err))
}
{
const functionName = "JsCreateContext"
ret, _, err := syscall.Syscall(
uintptr(jsCreateContext),
2,
uintptr(runtime),
uintptr(unsafe.Pointer(&context)),
uintptr(0),
)
if err := getJSError(ret); err != nil {
panic(fmt.Sprintf("%s failed: %s", functionName, err))
}
fmt.Print(fmt.Sprintf("%s: context: %v | error code: %v | dll call error: %v\n", functionName, context, ret, err))
}
{
const functionName = "JsSetCurrentContext"
ret, _, err := syscall.Syscall(
uintptr(jsSetCurrentContext),
1,
uintptr(context),
uintptr(0),
uintptr(0),
)
if err := getJSError(ret); err != nil {
panic(fmt.Sprintf("%s failed: %s", functionName, err))
}
fmt.Print(fmt.Sprintf("%s: error code: %v | dll call error: %v\n", functionName, ret, err))
}
{
const functionName = "JsRunScript"
context := 1
str, err := syscall.UTF16PtrFromString(jsExample)
if err != nil {
panic(err)
}
url, err := syscall.UTF16PtrFromString("")
if err != nil {
panic(err)
}
ret, _, err := syscall.Syscall6(
uintptr(jsRunScript),
4,
uintptr(unsafe.Pointer(str)),
uintptr(context),
uintptr(unsafe.Pointer(url)),
uintptr(unsafe.Pointer(&jsResult)),
uintptr(0),
uintptr(0),
)
if err := getJSError(ret); err != nil {
panic(fmt.Sprintf("%s failed: %s", functionName, err))
}
fmt.Print(fmt.Sprintf("%s: js result: %v | error code: %v | dll call error: %v\n", functionName, jsResult, ret, err))
}
{
const functionName = "JsConvertValueToString"
ret, _, err := syscall.Syscall(
uintptr(jsConvertValueToString),
2,
uintptr(jsResult),
uintptr(unsafe.Pointer(&resultJSString)),
uintptr(0),
)
if err := getJSError(ret); err != nil {
panic(fmt.Sprintf("%s failed: %s", functionName, err))
}
fmt.Print(fmt.Sprintf("%s: js convert val to string: %v | error code: %v | dll call error: %v\n", functionName, resultJSString, ret, err))
}
{
const functionName = "JsStringToPointer"
var utf16StringData *[0xffff]uint16
var stringLen uintptr
ret, _, err := syscall.Syscall(
uintptr(jsStringToPointer),
3,
uintptr(resultJSString),
uintptr(unsafe.Pointer(&utf16StringData)),
uintptr(unsafe.Pointer(&stringLen)),
)
if err := getJSError(ret); err != nil {
panic(fmt.Sprintf("%s failed: %s", functionName, err))
}
cStrData := syscall.UTF16ToString(utf16StringData[0 : stringLen])
fmt.Print(fmt.Sprintf("%s: js string: %s (len: %v) | error code: %v | dll call error: %v\n", functionName, cStrData, stringLen, ret, err))
}
return
}
func getJSError(errorCode uintptr) error {
switch (errorCode) {
case JsNoError:
return nil
case JsErrorInvalidArgument:
return errors.New("An argument to a hosting API was invalid. (JsErrorInvalidArgument)")
case JsErrorNullArgument:
return errors.New("An argument to a hosting API was null in a context where null is not allowed. (JsErrorNullArgument)")
case JsErrorScriptCompile:
return errors.New("JavaScript failed to compile. (JsErrorScriptCompile)")
default:
return fmt.Errorf("Unhandled error kind (%v).", errorCode)
}
}
Я получаю следующий вывод в консоли:
JsCreateRuntime: время выполнения: 0x3bd3310 | код ошибки: 0 | Ошибка вызова DLL:
Неверный параметр.
JsCreateContext: context: 0x3ce2000 |
код ошибки: 0 | Ошибка вызова DLL: операция успешно завершена.
JsSetCurrentContext: код ошибки: 0 | Ошибка вызова DLL: операция
успешно завершено.
JsRunScript: js результат: 0x3d00ac0 | ошибка
код: 0 | Ошибка вызова DLL: операция успешно завершена.
JsConvertValueToString: js преобразует val в строку: 0x3d00ac0 | ошибка
код: 0 | Ошибка вызова DLL: операция успешно завершена.
JsStringToPointer: js string: Hello world! (лен: 12) | код ошибки: 0 |
Ошибка вызова DLL: операция успешно завершена.