首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VB >

python 嵌入vb的有关问题,有vb原码,运行失败,望高人看看,不胜感激

2013-11-19 
python 嵌入vb的问题,有vb原码,运行失败,望高人看看,不胜感激本帖最后由 bcrun 于 2013-11-11 11:53:54 编

python 嵌入vb的问题,有vb原码,运行失败,望高人看看,不胜感激
本帖最后由 bcrun 于 2013-11-11 11:53:54 编辑

Private DeclareFunction Py_Initialize Lib "python25" () As Long
Private Declare Function Py_IsInitialized Lib "python25" () As Long
Private Declare Function Py_Finalize Lib "python25" () As Long

Private Declare Function Py_GetPath Lib "python25" () As Long
Private Declare Function Py_GetVersion Lib "python25" () As Long
Private Declare Function PyRun_SimpleString Lib "python25" (commandAs Any) As Long

Sub Main()
Py_Initialize
init = Py_IsInitialized
MsgBox init
MsgBox Py_GetPath
ver = PyGetVersion
MsgBox ver
PyRun_SimpleString "import sys"
PyRun_SimpleString "1+1"
PyRun_SimpleString "print 'Hello'*5" + Chr$(13)
Py_Finalize
End Sub

这是VB6中的代码,运行时提示“Dll调用约定错误” 在“PyRun_SimpleString "import sys"”这一行
请高手解答,
[解决办法]
Private Declare Function PyRun_SimpleString Lib "python25" (commandAs Any) As Long
->
Private Declare Function PyRun_SimpleString Lib "python25" (command As Any) As Long
[解决办法]
PyRun_SimpleString 可能和VB不兼容,它不遵循标准的stdcall调用约定,或者,你的函数原型不对。
[解决办法]

Declare Function PyRun_SimpleString CDecl Lib "python25" (ByVal Str As String) As Integer

看到有个代码这么声明的,看不懂,也没试过,试试看?
[解决办法]
引用:

Declare Function PyRun_SimpleString CDecl Lib "python25" (ByVal Str As String) As Integer

看到有个代码这么声明的,看不懂,也没试过,试试看?

我估计还是一样的效果。

“调用约定错误”,多数是参数个数不对。
所以,我觉得关键是“函数原型”可能不相符。

[解决办法]
引用:
Quote: 引用:


Declare Function PyRun_SimpleString CDecl Lib "python25" (ByVal Str As String) As Integer

看到有个代码这么声明的,看不懂,也没试过,试试看?

我估计还是一样的效果。

“调用约定错误”,多数是参数个数不对。
所以,我觉得关键是“函数原型”可能不相符。

这个CDecl在代码里他会变色,变成关键字的颜色,帮助里没说起这个关键字,但是调用约定错误里最后一条又在提这个

[解决办法]
不行,VB 不能直接调用 CDECL 的 DLL 函数,将触发约定错误。下面是一个通过处理调用 CDECL 的例子,但比较复杂。
[Visual Basic]
 
Imports System
Imports Microsoft.VisualBasic
Imports System.Runtime.InteropServices
Public Class LibWrap
' Visual Basic does not support varargs, so all arguments must be 
' explicitly defined. CallingConvention.Cdecl must be used since the stack 
' is cleaned up by the caller. 
' int printf( const char *format [, argument]... )
<DllImport("msvcrt.dll", CallingConvention := CallingConvention.Cdecl)> _
Overloads Shared Function printf ( _
    format As String, i As Integer, d As Double) As Integer
End Function
<DllImport("msvcrt.dll", CallingConvention := CallingConvention.Cdecl)> _
Overloads Shared Function printf ( _
    format As String, i As Integer, s As String) As Integer
End Function
End Class 'LibWrap
Public Class App
    Public Shared Sub Main()
        LibWrap.printf(ControlChars.CrLf + "Print params: %i %f", 99, 
                       99.99)
        LibWrap.printf(ControlChars.CrLf + "Print params: %i %s", 99, _
                       "abcd")
    End Sub 'Main
End Class 'App
   
[C#] 
using System;
using System.Runtime.InteropServices;
public class LibWrap
{
// C# doesn't support varargs so all arguments must be explicitly defined.


// CallingConvention.Cdecl must be used since the stack is 
// cleaned up by the caller.
// int printf( const char *format [, argument]... )
[DllImport("msvcrt.dll", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)]
public static extern int printf(String format, int i, double d); 
[DllImport("msvcrt.dll", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)]
public static extern int printf(String format, int i, String s); 
}
public class App
{
    public static void Main()
    {
        LibWrap.printf("\nPrint params: %i %f", 99, 99.99);
        LibWrap.printf("\nPrint params: %i %s", 99, "abcd");
    }
}

不妨用 VC++ 做一个 __stdcall 的 DLL 套一层,更简单一些。
[解决办法]
引用:
不行,VB 不能直接调用 CDECL 的 DLL 函数,将触发约定错误。下面是一个通过处理调用 CDECL 的例子,但比较复杂。
[Visual Basic]
 
Imports System
Imports Microsoft.VisualBasic
Imports System.Runtime.InteropServices
Public Class LibWrap
' Visual Basic does not support varargs, so all arguments must be 
' explicitly defined. CallingConvention.Cdecl must be used since the stack 
' is cleaned up by the caller. 
' int printf( const char *format [, argument]... )
<DllImport("msvcrt.dll", CallingConvention := CallingConvention.Cdecl)> _
Overloads Shared Function printf ( _
    format As String, i As Integer, d As Double) As Integer
End Function
<DllImport("msvcrt.dll", CallingConvention := CallingConvention.Cdecl)> _
Overloads Shared Function printf ( _
    format As String, i As Integer, s As String) As Integer
End Function
End Class 'LibWrap
Public Class App
    Public Shared Sub Main()
        LibWrap.printf(ControlChars.CrLf + "Print params: %i %f", 99, 
                       99.99)
        LibWrap.printf(ControlChars.CrLf + "Print params: %i %s", 99, _
                       "abcd")
    End Sub 'Main
End Class 'App
   
[C#] 
using System;
using System.Runtime.InteropServices;
public class LibWrap
{
// C# doesn't support varargs so all arguments must be explicitly defined.
// CallingConvention.Cdecl must be used since the stack is 
// cleaned up by the caller.
// int printf( const char *format [, argument]... )
[DllImport("msvcrt.dll", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)]
public static extern int printf(String format, int i, double d); 
[DllImport("msvcrt.dll", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)]
public static extern int printf(String format, int i, String s); 
}
public class App
{
    public static void Main()
    {
        LibWrap.printf("\nPrint params: %i %f", 99, 99.99);
        LibWrap.printf("\nPrint params: %i %s", 99, "abcd");
    }
}
不妨用 VC++ 做一个 __stdcall 的 DLL 套一层,更简单一些。


这哪里是什么“特殊处理”,这是VB.NET的代码。

如果要在VB中使用cdecl,需要按照相反的顺序传参数。然后需要某种技巧让调用者自己清栈(嵌入机器代码)。
[解决办法]
微软给的例子,直接 Copy 的。其实,网上还有一些 VB6 调用 CDECL 的例子,不过也都有缺陷,不能保证在所有情况下照做就能正常运行。

有关 VB 的下面三类问题,有许多“兴趣小制作”,不过最好是用 VC++ 辅助来绕过它们:

1 VB 实现多线程;
2 VB 编写“标准”DLL;
3 VB 调用 CDECL DLL。 

热点排行