Skip to content

Instantly share code, notes, and snippets.

@l0kod
Forked from calderonth/client.c
Last active April 16, 2023 01:56
Show Gist options
  • Save l0kod/e84c33be6e699d339ff8cfccd7b7cf69 to your computer and use it in GitHub Desktop.
Save l0kod/e84c33be6e699d339ff8cfccd7b7cf69 to your computer and use it in GitHub Desktop.
Using C struct and function pointers
/Cargo.lock
/target
[package]
name = "camlcrust"
version = "0.1.0"
exclude = [".gitignore"]
[lib]
name = "camlcrust"
#crate-type = ["staticlib"]
crate-type = ["cdylib"]
#include <stdio.h>
#include <dlfcn.h>
#include "libinternal.h"
int main( int argc, char *argv[]){
void *handle;
unsigned long rv, (*c_get_function_list)(struct my_function_list **);
struct my_function_list *functions_ptr;
handle = dlopen(argv[1], RTLD_NOW);
if (handle == NULL) {
printf("dlopen failed\n");
return 1;
}
/* Get the list of function pointers */
c_get_function_list = (unsigned long (*)(struct my_function_list **))
dlsym(handle, "C_GetFunctionList");
if (!c_get_function_list){
printf("C_GetFunctionList failed\n");
return 1;
}
// Call the function list getter
rv = c_get_function_list(&functions_ptr);
if(rv){
printf("C_GetFunctionList returned an error\n");
return 1;
}
// Call a function in the module through trampoline
functions_ptr->C_Initialize(NULL);
}
#include "libinternal.h"
// Define a struct containing all our functions
struct my_function_list function_list = {
C_Initialize,
C_GetFunctionList,
};
// A dummy function
unsigned long C_Initialize(void *init_args)
{
printf("Called from C_Initialize\n");
return 0;
}
// This is a getter function that returns the registered functions in the structure
unsigned long C_GetFunctionList(struct my_function_list ** ppFunctionList)
{
printf("Called from C_GetFunctionList\n");
if (ppFunctionList == NULL) {
printf("C_GetFunctionList: ppFunctionList is NULL\n");
return 1;
}
*ppFunctionList = &function_list;
return 0;
}
#![allow(non_snake_case)]
//extern crate libc;
use std::os::raw::c_ulong;
use std::os::raw::c_void;
#[derive(Copy, Clone)]
#[repr(C)]
struct FunctionList {
C_Initialize: extern "C" fn(_: *mut c_void) -> c_ulong,
C_GetFunctionList: extern "C" fn(_: *mut *const FunctionList) -> c_ulong,
}
// Define a struct containing all our functions
#[no_mangle]
static function_list: FunctionList = FunctionList {
C_Initialize: C_Initialize,
C_GetFunctionList: C_GetFunctionList,
};
// A dummy function
#[no_mangle]
extern "C" fn C_Initialize(_init_args: *mut c_void) -> c_ulong {
println!("Called from C_Initialize in Rust");
return 0;
}
#[no_mangle]
extern "C" fn C_GetFunctionList(ppFunctionList: *mut *const FunctionList) -> c_ulong {
println!("Called from C_GetFunctionList in Rust");
unsafe {
*ppFunctionList = &function_list;
}
return 0;
}
#include <stddef.h>
#include <stdio.h>
struct my_function_list;
typedef unsigned long (*CK_C_Initialize) (void *init_args);
typedef unsigned long (*CK_C_GetFunctionList) (struct my_function_list ** my_function_list);
unsigned long C_Initialize (void *init_args);
unsigned long C_GetFunctionList (struct my_function_list ** my_function_list);
struct my_function_list {
CK_C_Initialize C_Initialize;
CK_C_GetFunctionList C_GetFunctionList;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment