Skip to content

Instantly share code, notes, and snippets.

@mlh758
Last active April 3, 2019 20:45
Show Gist options
  • Save mlh758/045bcc4dff78f7405791a97060214270 to your computer and use it in GitHub Desktop.
Save mlh758/045bcc4dff78f7405791a97060214270 to your computer and use it in GitHub Desktop.
FFI Segfaulting
// +build mage
package main
import (
"fmt"
"os"
"os/exec"
"github.com/magefile/mage/mg"
)
// Create the shared lib
func Build() error {
fmt.Println("Compiling shared library...")
cmd := exec.Command("go", "build", "-o", "object-loader.dylib", "-buildmode=c-shared", "main.go")
return cmd.Run()
}
// Put the libs somewhere Ruby can find it
func Install() {
mg.Deps(Build)
fmt.Println("Installing...")
os.Rename("./object-loader.dylib", "/usr/local/lib/object-loader.dylib")
os.Rename("./object-loader.h", "/usr/local/lib/object-loader.h")
}
// Clean up after yourself
func Clean() {
fmt.Println("Cleaning...")
os.Remove("object-loader.dylib")
os.Remove("object-loader.h")
}
// Make sure it runs from C
func TestC() {
mg.Deps(Build)
fmt.Println("Compiling C program")
exec.Command("gcc", "-o", "test", "test.c", "./object-loader.dylib").Run()
results, _ := exec.Command("./test").Output()
fmt.Println("Testing it...")
fmt.Print(string(results))
os.Remove("./test")
}
package main
import (
"database/sql"
"fmt"
"log"
"C"
_ "gopkg.in/goracle.v2"
)
var db *sql.DB
func init() {
var err error
connString := "" // connection string to database
db, err = sql.Open("goracle", connString)
if err != nil {
log.Printf("Unable to connect to database: %v", err)
}
}
//export LoadObject
func LoadObject(id int) *C.char {
fmt.Println("Starting Query...")
rows, err := db.Query("select * from users where id = :1", id)
fmt.Println("Ran query")
if err != nil {
fmt.Printf("Unable to run query: %v\n", err)
return C.CString("Failed to run query")
}
fmt.Println("Accessing rows")
defer rows.Close()
for rows.Next() {
fmt.Println("Found a row")
}
fmt.Println("Returning")
return C.CString("All done")
}
func main() {
}
#include <stdio.h>
#include "object-loader.h"
int main()
{
GoInt userID = 4157737;
char *result;
result = LoadObject(userID);
printf("%s", result);
return 0;
}
# frozen_string_literal: true
require 'ffi'
module ObjectLoader
extend FFI::Library
ffi_lib 'object-loader.dylib'
attach_function :LoadObject, [:int], :string
end
threads = []
3.times do
threads << Thread.new { puts ObjectLoader.LoadObject(31_859_085) }
end
threads.each(&:join)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment