Posts: 1,031
Threads: 246
Joined: Jul 2022
03-15-2023, 10:32 PM
(This post was last modified: 06-04-2023, 12:00 PM by Davider.)
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
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;
}
Posts: 1,031
Threads: 246
Joined: Jul 2022
06-04-2023, 12:01 PM
(This post was last modified: 06-04-2023, 12:16 PM by Davider.)
Resolved, but may not be perfect
Macro Macro9
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
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:
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:
#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;
}
|