Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Tcc compiles c code and returns an array
#1
Hi,

The following c code defines a function tok2, which can use unicode characters as delimiters. How do I return an array? How to compile and execute in memory?

Thanks in advance for any suggestions and help
david

Macro Macro23
Code:
Copy      Help
def _DLL_tok "$desktop$\tok2.dll"
UnloadDll(_DLL_tok)

__Tcc x.Compile("" _DLL_tok 2)

dll- _DLL_tok $tok2 $s $se

_s="A┋B┋C┋D"
out tok2(_s "┋")

UnloadDll(_DLL_tok)

#ret
#include <stdio.h>
#include <string.h>

void split(char *src,const char *separator,char **dest,int *num) {
,char *pNext;
,int count = 0;
,if (src == NULL || strlen(src) == 0)
,,return;
,if (separator == NULL || strlen(separator) == 0)
,,return;
,char *strtok(char *str, const char *delim);
,pNext = strtok(src,separator);
,while(pNext != NULL) {
,,*dest++ = pNext;
,,++count;
,,pNext = strtok(NULL,separator);
,}
,*num = count;
}

__declspec(dllexport) char* tok2(const char* s,char *separator)
{
,char str[100];
,char *p[10]={0};
,int num=0,i;
,split(s,separator,p,&num);
,for(i = 0;i < num; i ++) {
,,printf("%s\n",p[i]);
,}
,return p[1];
,//return 0;
}
#2
Resolved, but may not be perfect

Macro Macro9
Code:
Copy      Help
dll- "" $tok2 $s $se

__Tcc t.Compile("" "tok2"); &tok2=t.f

_s="A┋B┋C┋D┋E"
out tok2(_s "┋")

#ret
#include <stdio.h>
#include <string.h>

#define EXPORT __declspec(dllexport)

void split(char* src,const char* separator,char** dest,int* num) {
,char *pNext;
,int count = 0;
,if (src == NULL || strlen(src) == 0)
,,return;
,if (separator == NULL || strlen(separator) == 0)
,,return;
,char *strtok(char *str, const char *delim);
,pNext = strtok(src,separator);
,while(pNext != NULL) {
,,*dest++ = pNext;
,,++count;
,,pNext = strtok(NULL,separator);
,}
,*num = count;
}
EXPORT char* tok2(char* s,char* separator)
{
,char str[100];
,char *p[10]={0};
,int num=0,i;
,split(s,separator,p,&num);
,char* result = (char*)malloc(100*sizeof(char));
,strcpy(result, p[0]);
,strcat(result, "\n");
,for (i = 1; i < num; i++) {
,,strcat(result, p[i]);
,,if (i != num-1) {
,,,strcat(result, "\n");
,,}
,}
,return result;
}

I want to achieve my goal in another way, but I have encountered some difficulties (I want to convert C # code into QM code)

Macro Macro11
Code:
Copy      Help
dll- "" split2 $s $sep lpstr*r n

__Tcc t.Compile("" "split2"); &split2=t.f

str s="A┋B┋C┋D┋E"
str sep="┋"

lpstr* r
int n
split2(s sep &r &n)
out r
out n

#ret
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define EXPORT __declspec(dllexport)

//Split a string into substrings by separator, and save them in a result array.
EXPORT void split2(const char* str, const char* sep, char*** result, int* n) {
int len_str = strlen(str);
int len_sep = strlen(sep);
int max_len = len_str / len_sep + 1; // Maximum number of possible substrings

char** res = (char**)malloc((max_len + 1) * sizeof(char*)); // Allocate memory, one more slot for storing NULL

if(res == NULL) {
;;;;printf("Memory allocation failed\n");
;;;;exit(EXIT_FAILURE);
}

memset(res, 0, (max_len + 1) * sizeof(char*)); // Initialize the array to NULL

int idx = 0;
char* token = strtok((char*)str, sep);
while (token != NULL) {
;;;;res[idx] = (char*)malloc((strlen(token) + 1) * sizeof(char)); // Allocate memory
;;;;strcpy(res[idx], token); // Copy the string to the newly allocated memory space
;;;;token = strtok(NULL, sep); // Take out a matching substring at a time
;;;;idx++;
}

*result = res;
*n = idx;
}

The following C # code can successfully call the split2 function in the split2. dll generated by the split2.c file

c# code:
Code:
Copy      Help
using System;
using System.Runtime.InteropServices;

class Program
{
// Import the "split2" function from the DLL
[DllImport(@"C:\Users\Administrator\Desktop\split2.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void split2(string str, string sep, out IntPtr resultPtr, out int n);

static void Main(string[] args)
{
    string str = "A┋B┋C┋D┋E";
    string sep = "┋";

    // Call the "split2" function
    IntPtr resultPtr;
    int n;
    split2(str, sep, out resultPtr, out n);

    // Convert the result to a string array
    string[] result = new string[n];
    for (int i = 0; i < n; i++)
    {
        IntPtr ptr = Marshal.ReadIntPtr(resultPtr, i * IntPtr.Size);
        result[i] = Marshal.PtrToStringAnsi(ptr);
    }

    // Print the split result
    foreach (string s in result)
        Console.WriteLine(s);
}
}

split2.c    code:
Code:
Copy      Help
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define EXPORT __declspec(dllexport)

//Split a string into substrings by separator, and save them in a result array.
EXPORT void split2(const char* str, const char* sep, char*** result, int* n) {
int len_str = strlen(str);
int len_sep = strlen(sep);
int max_len = len_str / len_sep + 1; // Maximum number of possible substrings

char** res = (char**)malloc((max_len + 1) * sizeof(char*)); // Allocate memory, one more slot for storing NULL

if(res == NULL) {
    printf("Memory allocation failed\n");
    exit(EXIT_FAILURE);
}

memset(res, 0, (max_len + 1) * sizeof(char*)); // Initialize the array to NULL

int idx = 0;
char* token = strtok((char*)str, sep);
while (token != NULL) {
    res[idx] = (char*)malloc((strlen(token) + 1) * sizeof(char)); // Allocate memory
    strcpy(res[idx], token); // Copy the string to the newly allocated memory space
    token = strtok(NULL, sep); // Take out a matching substring at a time
    idx++;
}

*result = res;
*n = idx;
}


Forum Jump:


Users browsing this thread: 1 Guest(s)