字符串数组导出问题

ilovedrv 2009-08-06 10:18:03
我封装了一个库,需要定义一个接口,返回字符串数组,如何定义这个接口,我大概想了下,大概有这样几种方法,希望大家能给些意见和建议啊

1) 专门用c++的stl库,大概如下形式

void get_var(list<string> *var_list)


这样可以再其它的工程中调用这个接口,比较方便,不过有个两个问题:
第一是我的库是纯c写的,不希望因为这个导入c++;
另外如果用stl的话,不同的工具和stl是不具备兼容性的

2) 第二种办法就是用用字符串指针,大概如下形式

void get_var(char **var_list, int *size)


第一次调用,var_list置空,返回size,即有几个字符串,由上层分配内存,第二次调用,则将字符串列表返回出去

这也问题:

第一,字符串也有长度,所以完善的做法是不仅要返回多少个字符串,还要返回每个字符串的长度
第二,会造成时间浪费,上层如果是用stl之类的存储字符串数组,则要先转换字符串指针数组到stl字符串链表转换

3)第三种办法,类似于枚举回调函数,即每次返回一个字符串,知道返回失败为止

void get_var(char *var_list, int *size)
这个size就是字符串长度了

一直调用该函数,知道失败为止,可是这个有点问题,在库里面需要记住枚举顺序,而且这个也有时间浪费


...全文
161 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
kojie_chen 2009-08-07
  • 打赏
  • 举报
回复
pass
zhusizhi007 2009-08-07
  • 打赏
  • 举报
回复
高手太多,只能学习中。。。。。。。
lzy0001sl 2009-08-07
  • 打赏
  • 举报
回复
云集各路大神啊,只能望洋兴叹了。
fallening 2009-08-07
  • 打赏
  • 举报
回复
我觉得可以包装一下

struct
string_arr
{
string* string_;
size_t size;
};


然后使用string_arr这个数据单元

void get_var( string_arr* string_list );
baihacker 2009-08-07
  • 打赏
  • 举报
回复
可以考虑一下类似NtQuerySystemInformation的处理方法,下面是能示例NtQuerySystemInformation的处理过程的代码:


#include "stdafx.h"
#include <windows.h>
#include "winternl.h"
#include <stddef.h>
#define STATUS_SEVERITY_WARNING 0x2
#define STATUS_SEVERITY_SUCCESS 0x0
#define STATUS_SEVERITY_INFORMATIONAL 0x1
#define STATUS_SEVERITY_ERROR 0x3

char result[sizeof(SYSTEM_PROCESS_INFORMATION)*1000];

typedef NTSTATUS (WINAPI *NtQuerySystemInformationType)(
__in SYSTEM_INFORMATION_CLASS SystemInformationClass,
PVOID SystemInformation,
__in ULONG SystemInformationLength,
__out_opt PULONG ReturnLength
);

typedef struct _CLIENT_ID {
HANDLE UniqueProcess;
HANDLE UniqueThread;
} CLIENT_ID;
typedef CLIENT_ID *PCLIENT_ID;
typedef LONG KPRIORITY;
typedef enum _KWAIT_REASON {
Executive,
FreePage,
PageIn,
PoolAllocation,
DelayExecution,
Suspended,
UserRequest,
WrExecutive,
WrFreePage,
WrPageIn,
WrPoolAllocation,
WrDelayExecution,
WrSuspended,
WrUserRequest,
WrEventPair,
WrQueue,
WrLpcReceive,
WrLpcReply,
WrVirtualMemory,
WrPageOut,
WrRendezvous,
Spare2,
Spare3,
Spare4,
Spare5,
Spare6,
WrKernel,
MaximumWaitReason
} KWAIT_REASON;
struct _SYSTEM_THREADS
{
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER CreateTime;
ULONG WaitTime;
PVOID StartAddress;
CLIENT_ID ClientIs;
KPRIORITY Priority;
KPRIORITY BasePriority;
ULONG ContextSwitchCount;
ULONG ThreadState;
KWAIT_REASON WaitReason;
};
typedef struct _VM_COUNTERS {
SIZE_T PeakVirtualSize;
SIZE_T VirtualSize;
ULONG PageFaultCount;
SIZE_T PeakWorkingSetSize;
SIZE_T WorkingSetSize;
SIZE_T QuotaPeakPagedPoolUsage;
SIZE_T QuotaPagedPoolUsage;
SIZE_T QuotaPeakNonPagedPoolUsage;
SIZE_T QuotaNonPagedPoolUsage;
SIZE_T PagefileUsage;
SIZE_T PeakPagefileUsage;
} VM_COUNTERS;
typedef VM_COUNTERS *PVM_COUNTERS;
struct _SYSTEM_PROCESSES
{
ULONG NextEntryOffset;
ULONG ThreadCount;
ULONG Reserved[6];
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ProcessName;
KPRIORITY BasePriority;
ULONG ProcessId;
ULONG InheritedFromProcessId;
ULONG HandleCount;
ULONG Reserved2[2];
VM_COUNTERS VmCounters;
IO_COUNTERS IoCounters; //windows 2000 only
struct _SYSTEM_THREADS Threads[1];
};

struct _SYSTEM_PROCESSES_
{
ULONG NextEntryOffset; //下一个进程信息的偏移量,如果为0表示无一个进程信息
ULONG ThreadCount; //线程数量
ULONG Reserved[6]; //
LARGE_INTEGER CreateTime; //创建进程的时间
LARGE_INTEGER UserTime; //进程中所有线程在用户模式运行时间的总和
LARGE_INTEGER KernelTime; //进程中所有线程在内核模式运行时间的总和
UNICODE_STRING ProcessName; //进程的名字
int r[5];
};

int _tmain(int argc, _TCHAR* argv[])
{
int cnt = 0;
DWORD dwTran;
SYSTEM_INFORMATION_CLASS sic = SystemProcessInformation;
HMODULE Lib = LoadLibrary(_T("ntdll.dll"));
NtQuerySystemInformationType proc =
(NtQuerySystemInformationType) GetProcAddress(Lib, "NtQuerySystemInformation");
NTSTATUS rc = (*proc)(
sic,
result,
sizeof(SYSTEM_PROCESS_INFORMATION)*1000,
&dwTran);
if (rc != STATUS_SEVERITY_SUCCESS)
{
return 5;
}
_SYSTEM_PROCESSES * curr = (_SYSTEM_PROCESSES*)result;
while (curr)
{
++cnt;
_tprintf(_T("%d\t"), curr->ProcessId);
_tprintf(_T("%s\t"), curr->ProcessName.Buffer);
_tprintf(_T("%d\t"), curr->NextEntryOffset);
_tprintf(_T("%d\n"), curr->ThreadCount);
_tprintf(_T("%d\t"), (int)curr+offsetof(_SYSTEM_PROCESSES,Threads)+sizeof(_SYSTEM_THREADS) * curr->ThreadCount);
_tprintf(_T("%d\n"), (int)curr+curr->NextEntryOffset);

if (curr->NextEntryOffset)
{
if (curr->NextEntryOffset-offsetof(_SYSTEM_PROCESSES,Threads)-sizeof(_SYSTEM_THREADS) * curr->ThreadCount
> sizeof(_SYSTEM_PROCESSES))
{
_tprintf(_T("hide process\n"));
}
*(char**)&curr += curr->NextEntryOffset;
}
else
{
curr = NULL;
}
}
printf("total\t%d\n", cnt);

int it[256];
int temp;
// ReadProcessMemory(GetCurrentProcess(), (void*)0xffdff124, it,16, &dwTran);
for (unsigned int i = 0; i < 256; ++i)
{
unsigned addr = 0xffdf124+i;
__asm
{
mov eax, addr
mov temp, eax
}
it[i] = temp;
}
for (int i = 0, brk = 0; i < 1024; ++i)
{
_tprintf(_T("%02x"), *((unsigned char*)it + i));
if (!(++brk&0x1F)) _tprintf(_T("\n"));
}
_tprintf(_T("\n%d\n"), GetLastError());
getchar();
return 0;
}
ilovedrv 2009-08-07
  • 打赏
  • 举报
回复
我也比较倾向于包装一下,不过比较担心速度

运行环境大概是这样:

Xscale 270 Arm 平台, linux操作系统 ,软件环境类似于宿主程序和lua的关系。

我实现了一个basic解释器,该解释器能够接受宿主程序的内存, 如上就是 字符串链表传入到basic解释器,用户可以直接编写basic脚本程序操作该字符串链表,宿主程序调用basic解释器后,将经过处理的字符创列表返回到宿主空间,然后又其它程序段处理,整个过程时间越少越好
ilovedrv 2009-08-07
  • 打赏
  • 举报
回复
初步定成这样了:


#define STRING_LEN 64
#define VAR_NUM 10

// 返回变量个数
int get_var_num()
{
return VAR_NUM;
}

// 获取变量名称
void get_var(char *val_list[], int str_size[], int size)
{
for (int i = 0; i < size; ++i)
{
if (val_list && str_size && str_size[i] == STRING_LEN)
sprintf(val_list[i], "string%d", i);
if (str_size)
str_size[i] = STRING_LEN;
}
}


int main(int argc, char* argv[])
{
int n = get_var_num();

int *str_size = new int[n];
char **val_list = new char *[n];

vector<string> v;
v.resize(n);

get_var(NULL, str_size, n);

int i = 0;
for(vector<string>::iterator it = v.begin(); it != v.end(); ++it, ++i)
{
string &str = (*it);
str.reserve(str_size[i]);
val_list[i] = (char *)str.c_str();
}

get_var(val_list, str_size, n);

for(it = v.begin(); it != v.end(); ++it)
printf("vector item %s\n", (*it).c_str());

delete []str_size;
delete []val_list;

return 0;
}
mstlq 2009-08-06
  • 打赏
  • 举报
回复
可以考虑导出两个函数吗?
我觉得第二个方法挺好的


int getsize(viod);
void get_var(char **var_list, int size[])



或者还是第二种方案,使用下面接口


int get_var(char **var_list, int size[])


返回值是字符串个数
调用后,数组size[]将记住每串字符的长度^_^
expter 2009-08-06
  • 打赏
  • 举报
回复
第三种方式 是不是第二种方式的第二步?

你第二种方法中为撒需要调用二次呢?
你可以在读取数据的时候分配内存撒?
mstlq 2009-08-06
  • 打赏
  • 举报
回复
第二种方法的问题二好像在第三种方法里面也会出现>_<

关于第二种方法,请问第二次调用void get_var(char **var_list, int *size)的时候,楼主的完善方案是打算从第二个形参返回一个int size数组,用来标记每一个字符串的长度吗^_^?

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧