add nullptr to perform_search

we need a nullptr at the end, to show where the list ends.
This commit is contained in:
千住柱間 2024-12-22 12:42:33 -04:00
commit 730f93b9c8
Signed by: hashirama
GPG key ID: 53E62470A86BC185
4 changed files with 58 additions and 7 deletions

View file

@ -1,4 +1,3 @@
# Compiler and flags
CXX = g++
CC = gcc
CXXFLAGS = -shared -fPIC
@ -7,7 +6,7 @@ LDFLAGS = -L. -ltrie_loader -Wl,-rpath=.
# Paths and files
LIBRARY_NAME = libtrie_loader.so
EXECUTABLE_NAME = wrapper_executable
SRC_CPP = libtrie_loader.hpp
SRC_CPP = libtrie_loader.cpp
SRC_C = main.c
# Targets

47
haskell.hs Normal file
View file

@ -0,0 +1,47 @@
{-# LANGUAGE ForeignFunctionInterface #-}
{-
$ ghc -o my_program Haskell.hs -L. -ltrie_loader
-}
import Foreign
import Foreign.C
import Control.Monad (when)
-- Declare the C functions
foreign import ccall "load_trie" loadTrie :: CString -> IO (Ptr ())
foreign import ccall "perform_search" performSearch :: Ptr () -> CString -> Ptr CSize -> IO (Ptr (Ptr CChar))
foreign import ccall "free_trie" freeTrie :: Ptr () -> IO ()
foreign import ccall "free_search_results" freeSearchResults :: Ptr (Ptr CChar) -> IO ()
main :: IO ()
main = do
-- Just call the functions, do nothing with the result
putStrLn "Calling load_trie..."
-- Load the trie (don't care about the result)
dictFile <- newCString "/home/hashirama/.local/share/hakurei/dict.bin"
trieHandle <- loadTrie dictFile
if trieHandle == nullPtr
then putStrLn "Failed to load trie"
else putStrLn "Trie loaded successfully"
putStrLn "Calling perform_search..."
-- Perform search (we care about the result here)
searchStr <- newCString "電気通信業務取扱規程"
resultCount <- malloc :: IO (Ptr CSize)
resultsPtr <- performSearch trieHandle searchStr resultCount
when (resultsPtr /= nullPtr) $ do
-- If results are returned, process them
-- Dereference the first result in the results pointer
firstResult <- peek resultsPtr >>= peekCString
putStrLn $ "First search result: " ++ firstResult
-- Free the search results (assuming we have a way to handle multiple results)
freeSearchResults resultsPtr
putStrLn "Calling free_trie..."
-- Free the trie (again, no checks, just call)
freeTrie trieHandle
putStrLn "Functions were called"

View file

@ -2,6 +2,7 @@
#include <string>
#include <iostream>
#include <vector>
#include <string.h> // for strdup
typedef void* TrieHandle; // Opaque pointer to represent the trie in C
@ -31,7 +32,6 @@ TrieHandle load_trie_from_cstring(const char* cstr) {
}
// C++ function to perform prefix search and return results as a dynamically allocated array of strings (C-compatible)
const char** search_prefix(TrieHandle handle, const char* search_str, size_t* result_count) {
xcdat::trie_15_type* trie = reinterpret_cast<xcdat::trie_15_type*>(handle);
xcdat::trie_15_type::prefix_iterator itr = trie->make_prefix_iterator(search_str);
@ -42,18 +42,23 @@ const char** search_prefix(TrieHandle handle, const char* search_str, size_t* re
results.push_back(std::string(itr.decoded_view()));
}
// Allocate memory to store the results
// Allocate memory to store the results + 1 for the null terminator
*result_count = results.size();
const char** result_array = new const char*[*result_count];
const char** result_array = new const char*[*result_count + 1]; // +1 for null pointer
// Copy the results from the vector to the array
for (size_t i = 0; i < *result_count; ++i) {
result_array[i] = results[i].c_str(); // Store the raw pointer to the string data
result_array[i] = strdup(results[i].c_str()); // Dynamically allocate strings
}
// Add a null terminator
result_array[*result_count] = nullptr;
return result_array;
}
// C territory
// Wrapper function to load the trie, for C usage

2
main.c
View file

@ -23,7 +23,7 @@ int main() {
size_t result_count = 0;
// Perform the search using the wrapper function
const char** results = perform_search(trie_handle, "真珠湾降", &result_count);
const char** results = perform_search(trie_handle, "よくない影響", &result_count);
// Print all the results
printf("Results found:\n");