Skip to content

Commit

Permalink
Extended type support for c_loader, improve search of headers and lib…
Browse files Browse the repository at this point in the history
…raries for c_loader, assuming now they are not in the same folder, add test with support for pointers to pointers in c_loader.
  • Loading branch information
viferga committed Nov 13, 2024
1 parent ef34cb7 commit 6cc27dc
Show file tree
Hide file tree
Showing 7 changed files with 165 additions and 14 deletions.
59 changes: 55 additions & 4 deletions source/loaders/c_loader/source/c_loader_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -244,13 +244,16 @@ typedef struct loader_impl_c_handle_dynlink_type : loader_impl_c_handle_base_typ

this->load_dynlink(lib_dir, lib_name.c_str());

/* If the path is absolute, we assume the header is in the same folder */
if (this->lib != NULL)
{
return this->add_header(lib_dir, lib_name);
}
}
else
{
bool header_found = false;

for (auto exec_path : c_impl->execution_paths)
{
fs::path absolute_path(exec_path);
Expand All @@ -259,11 +262,23 @@ typedef struct loader_impl_c_handle_dynlink_type : loader_impl_c_handle_base_typ

std::string lib_name = lib_path.filename().string();

this->load_dynlink(absolute_path.c_str(), lib_name.c_str());
/* If the path is relative, we keep trying the exec_paths until we find the header,
* this is for solving situations where we have the header in /usr/local/include and
* the library in /usr/local/lib
*/
if (this->lib == NULL)
{
this->load_dynlink(absolute_path, lib_name.c_str());
}

if (header_found == false)
{
header_found = this->add_header(absolute_path, lib_name);
}

if (this->lib != NULL)
if (this->lib != NULL && header_found == true)
{
return this->add_header(absolute_path, lib_name);
return true;
}
}
}
Expand All @@ -284,7 +299,7 @@ typedef struct loader_impl_c_handle_dynlink_type : loader_impl_c_handle_base_typ
}

private:
void load_dynlink(fs::path path, const char *library_name)
void load_dynlink(fs::path &path, const char *library_name)
{
/* This function will try to check if the library exists before loading it,
so we avoid error messages from dynlink when guessing the file path for relative load from file */
Expand Down Expand Up @@ -771,12 +786,46 @@ int c_loader_impl_initialize_types(loader_impl impl)
const char *name;
} type_id_name_pair[] = {
{ TYPE_BOOL, "bool" },

{ TYPE_CHAR, "char" },
{ TYPE_CHAR, "int8_t" },
{ TYPE_CHAR, "uint8_t" },
{ TYPE_CHAR, "int_least8_t" },
{ TYPE_CHAR, "uint_least8_t" },
{ TYPE_CHAR, "int_fast8_t" },
{ TYPE_CHAR, "uint_fast8_t" },

{ TYPE_SHORT, "short" },
{ TYPE_SHORT, "int16_t" },
{ TYPE_SHORT, "uint16_t" },
{ TYPE_SHORT, "int_least16_t" },
{ TYPE_SHORT, "uint_least16_t" },
{ TYPE_SHORT, "int_fast16_t" },
{ TYPE_SHORT, "uint_fast16_t" },

{ TYPE_INT, "int" },
{ TYPE_INT, "uint32_t" },
{ TYPE_INT, "int32_t" },
{ TYPE_INT, "int_least32_t" },
{ TYPE_INT, "uint_least32_t" },
{ TYPE_INT, "int_fast32_t" },
{ TYPE_INT, "uint_fast32_t" },

{ TYPE_LONG, "long" },
{ TYPE_LONG, "long long" },
{ TYPE_LONG, "uint64_t" },
{ TYPE_LONG, "int64_t" },
{ TYPE_LONG, "int_least64_t" },
{ TYPE_LONG, "uint_least64_t" },
{ TYPE_LONG, "int_fast64_t" },
{ TYPE_LONG, "uint_fast64_t" },
{ TYPE_LONG, "ptrdiff_t" },
{ TYPE_LONG, "intptr_t" },
{ TYPE_LONG, "uintptr_t" },

{ TYPE_FLOAT, "float" },
{ TYPE_DOUBLE, "double" },

{ TYPE_INVALID, "void" }

/* TODO: Do more types (and the unsigned versions too?) */
Expand Down Expand Up @@ -838,6 +887,8 @@ int c_loader_impl_execution_path(loader_impl impl, const loader_path path)
{
loader_impl_c c_impl = static_cast<loader_impl_c>(loader_impl_get(impl));

/* TODO: It would be interesting to support LD_LIBRARY_PATH or DYLD_LIBRARY_PATH
* on startup for supporting standard execution paths */
c_impl->execution_paths.push_back(path);

return 0;
Expand Down
2 changes: 1 addition & 1 deletion source/scripts/c/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ include(CProject)
add_subdirectory(compiled)
add_subdirectory(ffi)
add_subdirectory(cbks)
add_subdirectory(libloadtest)
add_subdirectory(loadtest)
9 changes: 0 additions & 9 deletions source/scripts/c/libloadtest/source/loadtest.cpp

This file was deleted.

File renamed without changes.
39 changes: 39 additions & 0 deletions source/scripts/c/loadtest/source/loadtest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#include "loadtest.h"
#include <cstdint>
#include <vector>

long call_cpp_func(void)
{
std::vector<int> v = { 7, 323, 14, 8 };

return v[1];
}

int pair_list_init(pair_list **t)
{
static const uint32_t size = 3;

*t = new pair_list();

(*t)->size = size;
(*t)->pairs = new pair[(*t)->size];

for (uint32_t i = 0; i < size; ++i)
{
(*t)->pairs[i].i = i;
(*t)->pairs[i].d = (double)(((double)i) * 1.0);
}

return 0;
}

double pair_list_value(pair_list *t, uint32_t id)
{
return t->pairs[id].d;
}

void pair_list_destroy(pair_list *t)
{
delete[] t->pairs;
delete t;
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,28 @@
extern "C" {
#endif

#include <cstdint>

typedef struct
{
uint32_t i;
double d;
} pair;

typedef struct
{
uint32_t size;
pair *pairs;
} pair_list;

EXPORT long call_cpp_func(void);

EXPORT int pair_list_init(pair_list **t);

EXPORT double pair_list_value(pair_list *t, uint32_t id);

EXPORT void pair_list_destroy(pair_list *t);

#ifdef __cplusplus
}
#endif
Expand Down
50 changes: 50 additions & 0 deletions source/tests/metacall_c_lib_test/source/metacall_c_lib_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,55 @@ TEST_F(metacall_c_lib_test, DefaultConstructor)

metacall_value_destroy(ret);

void *pair_list = NULL;

void *args_init[] = {
metacall_value_create_ptr(&pair_list),
};

ret = metacallv("pair_list_init", args_init);

EXPECT_NE((void *)NULL, (void *)ret);

EXPECT_EQ((enum metacall_value_id)metacall_value_id(ret), (enum metacall_value_id)METACALL_INT);

EXPECT_EQ((int)metacall_value_to_int(ret), (int)0);

metacall_value_destroy(ret);

metacall_value_destroy(args_init[0]);

void *args_value[] = {
metacall_value_create_ptr(pair_list),
metacall_value_create_int(2)
};

ret = metacallv("pair_list_value", args_value);

EXPECT_NE((void *)NULL, (void *)ret);

EXPECT_EQ((enum metacall_value_id)metacall_value_id(ret), (enum metacall_value_id)METACALL_DOUBLE);

EXPECT_EQ((double)metacall_value_to_double(ret), (double)2.0);

metacall_value_destroy(ret);

metacall_value_destroy(args_value[0]);
metacall_value_destroy(args_value[1]);

void *args_destroy[] = {
metacall_value_create_ptr(pair_list),
};

ret = metacallv("pair_list_destroy", args_destroy);

EXPECT_NE((void *)NULL, (void *)ret);

EXPECT_EQ((enum metacall_value_id)metacall_value_id(ret), (enum metacall_value_id)METACALL_INVALID);

metacall_value_destroy(ret);

metacall_value_destroy(args_destroy[0]);

EXPECT_EQ((int)0, (int)metacall_destroy());
}

0 comments on commit 6cc27dc

Please sign in to comment.