Giter Site home page Giter Site logo

dllcall's Introduction

DLLCall tool

DLLCall is an interface generator.

DLLCall will use a single go file as an interface description and from that file it will generate wrappers to call DLL implementing the same interface.

See why DLLCall for comparision between CGO and DLLCall interfaces.

Using DLLCall

Install DLLCall tool using go install github.com/lakal3/dllcall

Invoke: dllcall {interface}.go {c++ interface}.h

Example interface dbif.go

package {package name}

/*
#ctype Stmt *
*/
type stmtHandle uintptr

/*
#cmethod Open
#cmethod Close
*/
type dbIf struct{
	handle stmtHandle
	dbName string	
}

Generate interface

When we invoke dllcall tool such as dllcall dbif.go {otherdir}/dbif.h, dllcall will generate a dbif_impl_windows_amd64.go and dbif_impl_linux_amd64.go file into the current directory and dbif.h to a specified location.

The file name of dbif_impl_{os}_amd64.go is derived from the original go file name. C++ -file can be freely named.

You can use //go:generate directive and go generate command to easily upgrade the interface whenever it changes.

Interface definition

Interface definition must be a single go file containing only type definitions. You can't add functions or methods to the interface file.

Interface usage

After you have generated the interface, you can call it like any other go method

func main()  {
	err := load_dbif("docdbdll.dll") 
	// on Linux:  err := load_dbif(".\libdocdbdll.so") 
	if err != nil { log.Fatal( err )}
	d := &dbIf{ dbName: "test.db"}
	err = d.Open()
	if err != nil { log.Fatal( err )}
	/// ... Do something with db
	err = d.Close()
	if err != nil { log.Fatal( err )}
}

Generator will create an {interface}_impl_{os}_amd64.go file that contains all methods defined with #cmethod.

It will also contain load_{interface} method that takes a single file path to shared library (dll). How libraries are located depends on your operating system.

You must call load_{interface} before you try to invoke any other methods from interface.

Interface implementation

Generator will create a .h-file that you must include into the shared library project.

You must also implement the generated method stubs in a shared library project. In this example the methods to implement are:

GoError *dbIf::Open();
GoError *dbIf::Close();

For more detailed description of comment annotations, generation process and supported types, see generator or examples.

Cgocheck

Go 1.16 introduced new check that prevents pointers structures that contains pointer to Go memory. But in dllcall library all code must be aware of Go garbage collector and do not retain any references to structure member after call has been completed, so this check is unnecessary.

There are three ways to suppress this check

Pinned memory

In version 1.21 Go introduced new Pin mechanism that allows marking all pointer that we want to use in calls to C++ program so that Gos garbage collector is aware of them.

You can enable generating pinned memory pointer with -pin flag.

Pinning is a standard way to handle pointers to Go memory, but unfortunately it add some overhead to calls. Hello Example uses this method.

Disable cgocheck with code

Dllcall uses hack to turn off cgocheck. This hack is in function DisableCgocheck. Generated code will call this function when loading .dll/.so file.

If you select -pin option, cgocheck is not disabled because it will allow pinned memory pointers without panic. Pin option is available only in go 1.21 and later.

It is possible this hack will not work in some future version of Go, so you can change this function to disable this hack.

Windows

Actually Windows syscalls don't apply any checks for go pointers, so dllcall generator will not emit any code to disable checks of to pin memory even if -pin flag is given

Safe method (experimental)

In go 1.21.1 safemethod calls will fail because they set new value to SP (Stack pointer). This is due to change in go1.21. It has been fixed in go1.22 for Windows but Linux still

Added new experimental #csafe_method that mostly allows bypassing Go call overhead to native libraries. This method has several limitations and is experimental. See Generator and new sample fibon for more details.

You should only use fast call when absolutely necessary like accessing high resolution timer in Windows.

Status

Currently only 64 bit (amd64) Windows and 64 bit Linux (amd64) are supported.

Version 0.8.2 breaking changes

  • Renamed generated Go interface. Generated files have now _amd64 extension to prevent build on other architectures. To fix this, remove old generated files from project.
  • Linux CGO wrapper has been moved to a new package linux/syscall to support fastcall. Wrapper packages must be compiled without CGO.

TODO?

  • Pinned memory available with Go 1.21
  • Fastcall (Experimental)
  • Better support for types imported from other modules
  • Linux support

dllcall's People

Contributors

lakal3 avatar

Stargazers

Janne Lautamäki avatar abdul dakkak avatar

Watchers

James Cloos avatar  avatar

Forkers

listinvest

dllcall's Issues

Error when using in invrunner project

Hi.

The error message that I promised to send:

C:\repos\symetri\invrunner>go mod tidy
go: finding module for package bitbucket.symetri.com/sovcon/invrunner/soveliada
go: finding module for package github.com/lakal3/dllcall/linux/syscall
bitbucket.symetri.com/sovcon/invrunner/com imports
        github.com/lakal3/dllcall/linux/syscall: module github.com/lakal3/dllcall@latest found (v0.7.2), but does not contain package github.com/lakal3/dllcall/linux/syscall
bitbucket.symetri.com/sovcon/invrunner/modelexportserver imports
        bitbucket.symetri.com/sovcon/invrunner/soveliada: no matching versions for query "latest"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.