| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
共有 1555 人关注过本帖
标题:将核心加密算法,用C重写并封装至DLL,供vfp调用……字符串函数怎么办?
只看楼主 加入收藏
cssnet
Rank: 5Rank: 5
等 级:职业侠客
威 望:5
帖 子:588
专家分:383
注 册:2013-10-4
收藏
 问题点数:0 回复次数:18 
将核心加密算法,用C重写并封装至DLL,供vfp调用……字符串函数怎么办?
设一个函数f(x),输入参数x为字符串,返回值是加密后的字符串(准确地说,是字符指针或字符数组):
char* f(char* x)
感觉上,挺难处理得像 vfp 原生字符串函数那样,简单调用!比如,希望实现:
replace all myenc with f(mydec)
因,单独调用f(x)并非内存安全的,必须紧跟来一句free()。问deepseek,实现起来也有些复杂,DLL中须额外暴露一个函数 free_memory(char* ptr),以便调用者清理内存。

怎么破?

搜索更多相关主题的帖子: 字符串 函数 调用 加密 vfp 
2026-02-08 23:22
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:451
帖 子:11176
专家分:43605
注 册:2014-5-20
收藏
得分:0 
C方面负责释放函数自己分配而不再使用的资源。
vfp负责自己分配和释放资源,写个字符串类(主要包括分配、读写和释放方法)。在 init 事件或自定义方法分配资源;在 Destroy 事件释放分配的资源,使用时每个类实例生命期结束就会自动释放资源。

2026-02-09 10:21
cssnet
Rank: 5Rank: 5
等 级:职业侠客
威 望:5
帖 子:588
专家分:383
注 册:2013-10-4
收藏
得分:0 
看了一下 deepseek 提供的代码,大致步骤是:

    * 获取DLL返回值字符指针
    lnPtr = f(x)

    * 获取长度
    lnLen = GetStringLength(lnPtr)
   
    IF lnLen > 0
        lcResult = SYS(2600, lnPtr, lnLen)
    ELSE
        lcResult = ""
    ENDIF
   
    * 释放内存
    = free_memory(lnPtr)
   
    RETURN lcResult

这流程是靠谱的。
2026-02-09 10:24
cssnet
Rank: 5Rank: 5
等 级:职业侠客
威 望:5
帖 子:588
专家分:383
注 册:2013-10-4
收藏
得分:0 
DeepSeek 提供的完整代码:

程序代码:
1. C 语言 DLL 源代码 (crypto.c)
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

// DLL 导出宏
#ifdef _WIN32
    #define DLL_EXPORT __declspec(dllexport)
#else
    #define DLL_EXPORT
#endif

// 内存安全的字符串复制函数
static char* safe_strdup(const char* src) {
    if (src == NULL) return NULL;
    
    size_t len = strlen(src);
    char* dest = (char*)malloc(len + 1);
    if (dest == NULL) return NULL;
    
    memcpy(dest, src, len + 1);
    return dest;
}

// XOR 加密/解密函数
// 注意:加密和解密使用相同的函数(XOR 特性)
static char* xor_encrypt_decrypt(const char* input, const char* key) {
    if (input == NULL || key == NULL) return NULL;
    
    size_t input_len = strlen(input);
    size_t key_len = strlen(key);
    
    if (key_len == 0) return safe_strdup(input);
    
    char* result = (char*)malloc(input_len + 1);
    if (result == NULL) return NULL;
    
    for (size_t i = 0; i < input_len; i++) {
        result[i] = input[i] ^ key[i % key_len];
    }
    result[input_len] = '\0';
    
    return result;
}

// 统一的加密/解密接口函数
// 注意:使用相同的密钥 "SecretKey123!",实际使用时可以根据需要修改
DLL_EXPORT char* encode_decode(const char* input) {
    const char* key = "SecretKey123!";  // 固定的密钥
    return xor_encrypt_decrypt(input, key);
}

// 释放内存函数(必须导出,供 C# 调用释放内存)
DLL_EXPORT void free_memory(char* ptr) {
    if (ptr != NULL) {
        free(ptr);
    }
}

2. C 语言头文件 (crypto.h)
#ifndef CRYPTO_H
#define CRYPTO_H

#ifdef __cplusplus
extern "C" {
#endif

// 导出函数声明
char* encode_decode(const char* input);
void free_memory(char* ptr);

#ifdef __cplusplus
}
#endif

#endif // CRYPTO_H


VFP调用代码:
程序代码:
* 使用 VFP 内置函数处理内存
* 声明原始 DLL 函数
DECLARE INTEGER encode_decode IN crypto.dll STRING input
DECLARE INTEGER free_memory IN crypto.dll INTEGER ptr

* 使用 SYS([color=#800000]2600) 的封装函数[/color]
FUNCTION EncodeDecodeVFP(lcInput)
    LOCAL lnPtr, lcResult, lnLen
    
    IF EMPTY(lcInput)
        RETURN lcInput
    ENDIF
    
    * 调用 DLL
    lnPtr = encode_decode(lcInput)
    
    IF lnPtr = 0
        RETURN ""
    ENDIF
    
    * 方法1:使用 SYS(2600) 获取字符串
    * 先获取长度
    lnLen = GetStringLength(lnPtr)
    
    IF lnLen > 0
        lcResult = SYS(2600, lnPtr, lnLen)
    ELSE
        lcResult = ""
    ENDIF
    
    * 释放内存
    = free_memory(lnPtr)
    
    RETURN lcResult
ENDFUNC

* 辅助函数:获取 C 字符串长度
FUNCTION GetStringLength(lnPtr)
    LOCAL lnLen, lcChar, lnResult
    
    IF lnPtr = 0
        RETURN 0
    ENDIF
    
    lnResult = 0
    
    * 逐个字符查找 null 终止符
    DO WHILE .T.
        lcChar = SYS(2600, lnPtr + lnResult, 1)
        IF ASC(lcChar) = 0
            EXIT
        ENDIF
        lnResult = lnResult + 1
    ENDDO
    
    RETURN lnResult
ENDFUNC


2026-02-09 10:42
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:451
帖 子:11176
专家分:43605
注 册:2014-5-20
收藏
得分:0 
DeepSeek 对 vfp 某些方面的了解还不够
vfp 通常用的 ansi 字符串是可以包含 0h00,不能直接使用 C 的一些字符串处理函数。
C 默认字符串是以 0h00 结束,如  strlen() 计算到 0h00 就返回结果了。
2026-02-09 11:38
cssnet
Rank: 5Rank: 5
等 级:职业侠客
威 望:5
帖 子:588
专家分:383
注 册:2013-10-4
收藏
得分:0 
以下是引用吹水佬在2026-2-9 11:38:30的发言:

DeepSeek 对 vfp 某些方面的了解还不够
vfp 通常用的 ansi 字符串是可以包含 0h00,不能直接使用 C 的一些字符串处理函数。
C 默认字符串是以 0h00 结束,如  strlen() 计算到 0h00 就返回结果了。


我只是让 DeepSeek 提供一份完整的简单模板代码,并非直接套用它写的函数。
至于 0h00,一般在我的代码当中,会避免在字符串中出现——毕竟字符串主要处理的是中、英文,即便加密算法,刻意过滤掉结果中的 0h00 即可。
话说,没必要难为 C 代码。


2026-02-09 11:56
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:451
帖 子:11176
专家分:43605
注 册:2014-5-20
收藏
得分:0 
回复 6楼 cssnet
做加密算法不能不考虑0h00的出现情况,明文不存在不等于密文不存在。
指针的使用最好严格规范其两大属性:地址和大小,要出双入对。

[此贴子已经被作者于2026-2-9 12:21编辑过]

2026-02-09 12:19
DANSON
Rank: 2
等 级:论坛游民
帖 子:143
专家分:83
注 册:2025-10-4
收藏
得分:0 
回复 7楼 吹水佬
2026-02-09 12:50
cssnet
Rank: 5Rank: 5
等 级:职业侠客
威 望:5
帖 子:588
专家分:383
注 册:2013-10-4
收藏
得分:0 
以下是引用吹水佬在2026-2-9 12:19:58的发言:

做加密算法不能不考虑0h00的出现情况,明文不存在不等于密文不存在。
指针的使用最好严格规范其两大属性:地址和大小,要出双入对。


常规的做法,自然是传递第2个参数:字符串长度。
而,更常见的做法,是将返回值设成目标字符串长度,而第2个参数则存放加密结果字符串。即:
int f(char* cSrc, char* cDst)
cDst在VFP当中赋值,设置成足够长度的缓冲区。
可问题是,如此一来,就无法套用:
replace all dst with f(src)
这种人性化语法了!
而这也正是一开始我为之纠结的问题所在。

——怎么破?

2026-02-09 13:39
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:451
帖 子:11176
专家分:43605
注 册:2014-5-20
收藏
得分:0 
回复 9楼 cssnet
想得既简单又复杂了吧。
7楼说过“地址和大小,要出双入对”,这样做包没错。常常见到api用结构作参数来处理,都是一对 buffer和bufferSize同时出现。
replace all dst with f(src) 就要看 dst 是什么,f()也只能是密文的地址或长度,就算是vfp写个函数转一下也不是问题。
replace all dst with vf(f(src)) 这样不行吗?
2026-02-09 14:23
快速回复:将核心加密算法,用C重写并封装至DLL,供vfp调用……字符串函数怎么办 ...
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.020327 second(s), 9 queries.
Copyright©2004-2026, BCCN.NET, All Rights Reserved