| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
共有 399 人关注过本帖
标题:关于vfp9引用V8与python ,大家可以讨论一番
取消只看楼主 加入收藏
iswith
Rank: 8Rank: 8
等 级:蝙蝠侠
威 望:5
帖 子:716
专家分:732
注 册:2013-5-14
结帖率:3.13%
收藏
 问题点数:20 回复次数:8 
关于vfp9引用V8与python ,大家可以讨论一番
从设计层面而言,VFP 已能够实现对 V8 脚本的引用,从而支持 C#、V8 JS 与 VFP 三种语言的交互调用,且达成了无缝对接。这一成果本计划对外发布,但目前仍未推出 —— 主要原因在于相关文件体积过大,而我尚未解决不加密状态下文件体积成倍增长的问题,因此暂未发行。要知道,其原生文件就已超过 20MB。
至于 Python 的进程内无缝交互接入,参考 V8 的设计逻辑来看,可行性颇高。不过,涉及 Python 所需配套库(主要是 CPython)参与 VFP9 项目发行的相关内容,仍需进一步研究整理。好在就函数上下交互而言,目前基本不存在问题。
有二者,基本弥补 让vfp9生态不足,大家对二者有啥想法可以讨论一下。
搜索更多相关主题的帖子: 交互 python 文件 引用 vfp9 
前天 15:39
iswith
Rank: 8Rank: 8
等 级:蝙蝠侠
威 望:5
帖 子:716
专家分:732
注 册:2013-5-14
收藏
得分:0 
着重点在交互,你如果可以让两者语言重构以前的老软件业务,肯定用新语言,我的出发点是双方交互,要理解交互的意义,不是写个EXE  run EXE就叫交互,那是运行EXE。交互的意义是混合使用,弥补vfp无C库生态可用。其实cpython比较接近C语言性能了。在我的研究的中发现py是可以打包以极小MB包发行在vfpEXE里面的,如果什么都不学就原地固步自封,淘汰是迟早的,除了vfp外面的世界很精彩,如果直接让你精彩你都不知道从何开始,何不暂时跟着我立定的netpython一边走一边学一边看,也许py就学会了也说不定。。。。。

[此贴子已经被作者于2025-8-14 19:34编辑过]

前天 19:20
iswith
Rank: 8Rank: 8
等 级:蝙蝠侠
威 望:5
帖 子:716
专家分:732
注 册:2013-5-14
收藏
得分:0 
netpy.7z (2.44 KB)
前天 20:58
iswith
Rank: 8Rank: 8
等 级:蝙蝠侠
威 望:5
帖 子:716
专家分:732
注 册:2013-5-14
收藏
得分:0 
netpython 还是要调用 python版本 我封装开发测试用3.8版本 只是把python封装一下方便 交互调用
前天 22:59
iswith
Rank: 8Rank: 8
等 级:蝙蝠侠
威 望:5
帖 子:716
专家分:732
注 册:2013-5-14
收藏
得分:0 
这样的调用才可以互通有无,上下连接,才叫交互调用
图片附件: 游客没有浏览图片的权限,请 登录注册
前天 23:33
iswith
Rank: 8Rank: 8
等 级:蝙蝠侠
威 望:5
帖 子:716
专家分:732
注 册:2013-5-14
收藏
得分:0 
图片附件: 游客没有浏览图片的权限,请 登录注册
图片附件: 游客没有浏览图片的权限,请 登录注册
昨天 00:13
iswith
Rank: 8Rank: 8
等 级:蝙蝠侠
威 望:5
帖 子:716
专家分:732
注 册:2013-5-14
收藏
得分:0 
以下是引用ykxby001在2025-8-15 08:21:20的发言:

楼主可以自己建个网站,把你自己的好东西挂上卖


代码发出来就是让你参考的!ds复制粘贴就给出开发原型。买别人不如自己学会嘛!玩程序不都这样的思维咯!
昨天 10:06
iswith
Rank: 8Rank: 8
等 级:蝙蝠侠
威 望:5
帖 子:716
专家分:732
注 册:2013-5-14
收藏
得分:0 
以下是引用yiyanxiyin在2025-8-15 10:43:07的发言:

vfp的生态无法弥补, 历史的滚滚车轮已经碾压过了vfp及那个时代, 除非时光倒流......  让vfp做它该做的,别让它做不该它做的

是这个道理,没看到我没有让vfp9做,让cpython做!
昨天 10:56
iswith
Rank: 8Rank: 8
等 级:蝙蝠侠
威 望:5
帖 子:716
专家分:732
注 册:2013-5-14
收藏
得分:0 
*==============================================================
* 文件: test_netpy_examples.prg
* 说明: NetPy 调用示例(多个常见用法)
* 说明点:
*  - 假定同目录下有 NetPy.prg
*  - 请确认 lcPyDllPath 指向你本机的 pythonNN.dll 并且位数与编译的 NetPy.dll 一致 及32位,python38用于开发调器,建议一样。
*  - 发行Python38 所需文件请成为vip再咨询。文件整体压缩到不大只有几MB,但cPython库挺大的,最好建全商业应用的自动下载库发送指令给你的客户机;
     让其自动下载所需应用的库,升级应用调用就可以完成任务。
*  - 示例包含:ExecPy + _vfp.SetVar、oNetPy.CallFunc、从 Python 传数组回 VFP、numpy 处理、错误处理、清理
*==============================================================

* - 设置工作路径
Set Talk Off
Set Date YMD
Clear
On Shutdown Quit()

* - 工作目录
Local lcPath
If Type( "_vfp.ActiveProject" ) == "O"
    m.lcPath = JustPath( _vfp.ActiveProject.Name )
Else
    m.lcPath = JustPath( Sys(16) )
Endif
Set Default To ( m.lcPath )

If !File( "NetPy.prg" )
    ?"没找到 NetPy.prg,请先放到当前工作目录或指定路径"
    Return
Endif
Set Procedure To NetPy.prg

* - 初始化Python环境
Public oNetPy
If Vartype(oNetPy) <> "O" Or IsNull(oNetPy)
    oNetPy = CreateObject("oNetPy")
    Local lcPyDllPath
    * 修改为本机 Python dll 路径
    lcPyDllPath = [C:\Users\Administrator\AppData\Local\Programs\Python\Python38-32\python38.dll]

    If !oNetPy.InitPy(lcPyDllPath)
        ? "InitPy 失败:", oNetPy.cLastError
        Release oNetPy
        Return
    Endif
Endif

? "NetPy 版本:", oNetPy.GetVer()

? Replicate("=", 30)

* 注入 _vfp(供 Python 脚本调用)
Local lcErrorMsg
lcErrorMsg= ""
If !oNetPy.AddHostObject("_vfp", _vfp, @lcErrorMsg)
    ? "AddHostObject 失败:", lcErrorMsg
    Return
Endif

* ---------------------------
* 示例 1: 简单 ExecPy -> Python 里计算并通过 _vfp.SetVar 返回结果给 VFP
* ---------------------------
Local lcScript    ;
    , lcErrorMsg
   
m.lcErrorMsg= ""

Public result
Text To m.lcScript Noshow Pretext 2
    import math
    result = math.sqrt(25)

    # 通过注入的 _vfp.SetVar 把结果设置回 VFP 变量 result
    _vfp.SetVar( "result" , result )

    # 在 Python 端也通过 DoCmd 打印结果(可在 VFP 输出看到)
    _vfp.DoCmd('?"示例1:PY sqrt(25) -> " + str(result)')
Endtext

If !oNetPy.ExecPy( m.lcScript , @lcErrorMsg)
    ? "示例1:ExecPy 失败:", lcErrorMsg
    _cliptext = lcErrorMsg
Else
    ?"示例1:[vfp] sqrt(25) -> " , result
Endif
? Replicate("=", 30)


* ---------------------------
* 示例 2: 直接在 VFP 调用 Python 标准库函数(CallFunc)
*       使用 oNetPy.CallFunc(module, func, taParams, @tcErrorMsg)
* ---------------------------
Local laParams[2]    ;
    , loRes
   
laParams[1]     = 2
laParams[2]     = 8
m.lcErrorMsg    = ""

loRes = oNetPy.CallFunc( "math", "pow", @laParams, @lcErrorMsg )
If Empty( m.lcErrorMsg ) Then
    ? "示例2: math.pow(2,8) ->", loRes
Else
    ? "示例2 调用失败:", m.lcErrorMsg
    _cliptext  =  m.lcErrorMsg
Endif

? Replicate("=", 30)

* ---------------------------
* 示例 3: 在 Python 中定义函数并让 Python 直接通过 _vfp.SetVar 返回结果,
*          然后在 VFP 使用 GetVariable 读取(适合复杂函数和闭包)
* ---------------------------
Public res_add
Text To m.lcScript Noshow
def my_add(a, b):
    return a + b

res = my_add(7, 13)
_vfp.SetVar( "res_add" ,  res )
_vfp.DoCmd( f'?"[示例3:PY] my_add(7,13) -> " + str( {res} )' )
Endtext

lcErrorMsg = ""
If oNetPy.ExecPy( m.lcScript, @lcErrorMsg ) Then
    ? "示例3: res_add =", _vfp.Eval("res_add")
Else
    ? "示例3 ExecPy 失败:", lcErrorMsg
    _cliptext = lcErrorMsg
Endif

? Replicate("=", 30)

* ---------------------------
* 示例 4:Python 生成图表并返回图片路径
* ---------------------------
* Python 生成图表并返回图片路径
Text To lcScript Noshow Pretext 2
import matplotlib.pyplot as plt
import os

# 创建数据
x = [1, 2, 3, 4]
y = [10, 15, 13, 17]

# 生成图表
plt.plot(x, y)
plt.title('VFP-Python 交互图表')
img_path = os.path.join(_vfp.GetVar("sys(5)"), 'chart.png')
plt.savefig(img_path)
plt.close()

# 返回图片路径
_vfp.SetVar( "cImagePath" , img_path )
Endtext

If oNetPy.ExecPy( m.lcScript ) Then
    If File(cImagePath)
        _Screen.AddObject("imgChart", "Image")
        _Screen.imgChart.Picture = cImagePath
        _Screen.imgChart.Visible = .T.
    Endif
Endif

Return

* ---------------------------
* 示例 4: Python 把 list 传回 VFP(SetArray),并在 VFP 端读取数组内容
* ---------------------------
Text To m.lcScript Noshow
py_list = [1, 2, 3, 'he"llo', 5.5, True, None]
try:
    _vfp.SetArray( "py_list" ,  py_list )
except Exception as e:
    _vfp.DoCmd( f'?[PY] SetArray failed: str({e}) ')
Endtext

lcErrorMsg = ""
If !oNetPy.ExecPy(m.lcScript, @lcErrorMsg) Then
    ? "示例4 ExecPy 失败:", lcErrorMsg
    _cliptext = lcErrorMsg
Else
    * 检查 VFP 端是否存在 py_list,并打印元素
    If Type("py_list") = "U"
        ? "示例4: py_list 未在 VFP 创建"
    Else
        ? "示例4: py_list 类型:", Vartype(py_list)
        If Vartype(py_list) = "A"
            ? "示例4: py_list 元素数:", Alen(py_list)
            For lnI = 1 To Alen(py_list)
                ? "py_list[", lnI, "] =", py_list[lnI]
            Endfor
        Else
            ? "示例4: py_list 值:", py_list
        Endif
    Endif
Endif
? Replicate("=", 30)


* ---------------------------
* 示例 5: 使用 numpy 并把 ndarray 转为 list 再传给 VFP(更稳定)
* ---------------------------
Text To m.lcScript Noshow
try:
    import numpy as np
    py_nd = np.array([[10, 20, 30], [40, 50, 60]])
    # 将 ndarray 转成嵌套 list,再用 SetArray 逐行/逐元素写回
    _vfp.SetArray("py_nd", py_nd.tolist())
    _vfp.DoCmd('?"[PY] SetArray(py_nd.tolist()) called"')
except Exception as e:
    _vfp.DoCmd('?"[PY] numpy -> fallback list used or failed: ' + str(e) + '"')
    py_nd = [[10,20,30],[40,50,60]]
    _vfp.SetArray("py_nd", py_nd)
Endtext

lcErrorMsg = ""
If !oNetPy.ExecPy(m.lcScript, @lcErrorMsg)
    ? "示例5 ExecPy 失败:", lcErrorMsg
Else
    If Type("py_nd") = "U"
        ? "示例5: py_nd 未在 VFP 创建"
    Else
        ? "示例5: py_nd 类型:", Vartype(py_nd)
        If Vartype(py_nd) = "A"
            ? "示例5: py_nd 尺寸:", Alen(py_nd,1), "x", Alen(py_nd,2)
            For lnI = 1 To Alen(py_nd,1)
                For lnJ = 1 To Alen(py_nd,2)
                    ? "py_nd[", lnI, ",", lnJ, "] =", py_nd[lnI, lnJ]
                Endfor
            Endfor
        Else
            ? "示例5: py_nd 值:", py_nd
        Endif
    Endif
Endif

* ---------------------------
* 示例 6: Error handling 演示(捕获 ExecPy/CallFunc 错误并读取 oNetPy.cLastError)
* ---------------------------
* 故意调用不存在的模块/函数
Local laP[1], lcErrorMsg2, loBad
laP[1] = 10
m.lcErrorMsg = ""
loBad = oNetPy.CallFunc("non_existing_module", "foo", @laP, @lcErrorMsg )
If Empty(lcErrorMsg)
    ? "示例6: unexpected success ->", loBad
Else
    ? "示例6: 调用失败,错误信息:", lcErrorMsg
    ? "(保存的最后错误)", oNetPy.cLastError
Endif

* ---------------------------
* 清理:关闭 Python(根据需要)
* ---------------------------
* 如果你希望在脚本末尾释放 Python 环境:
* oNetPy.Shutdown()
* Release oNetPy

? "示例运行结束"
Return
昨晚 20:26
快速回复:关于vfp9引用V8与python ,大家可以讨论一番
数据加载中...
 
   



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

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.020372 second(s), 12 queries.
Copyright©2004-2025, BC-CN.NET, All Rights Reserved