在VB中如何嵌入C++代码?有什么特殊处理吗?是不是一样能进行编译。

解决方案 »

  1.   

    嵌不了吧?
    除非你先生成C++代码的汇编代码,在VB里嵌入汇编代码来执行该断程序
      

  2.   

    下面的例子完全用VB进行ASM编程的示例,本例获得CPU ID.工程文件分为一个form1.frm 和一个模块module1.bas----------------------form1.frm的源文件---------------------VERSION 5.00
    Begin VB.Form Form1 
       Caption         =   "Form1"
       ClientHeight    =   1965
       ClientLeft      =   60
       ClientTop       =   345
       ClientWidth     =   3105
       LinkTopic       =   "Form1"
       ScaleHeight     =   1965
       ScaleWidth      =   3105
       StartUpPosition =   2  'Bildschirmmitte
       Begin VB.CommandButton Command1 
          Caption         =   "Get CPU Name"
          Height          =   495
          Left            =   840
          TabIndex        =   0
          Top             =   315
          Width           =   1425
       End
       Begin VB.Label Label2 
          Alignment       =   2  'Zentriert
          AutoSize        =   -1  'True
          BeginProperty Font 
             Name            =   "MS Sans Serif"
             Size            =   9.75
             Charset         =   0
             Weight          =   400
             Underline       =   0   'False
             Italic          =   0   'False
             Strikethrough   =   0   'False
          EndProperty
          Height          =   240
          Left            =   1515
          TabIndex        =   2
          Top             =   1065
          Width           =   60
       End
       Begin VB.Label Label1 
          Alignment       =   2  'Zentriert
          AutoSize        =   -1  'True
          BeginProperty Font 
             Name            =   "Arial"
             Size            =   12
             Charset         =   0
             Weight          =   700
             Underline       =   0   'False
             Italic          =   0   'False
             Strikethrough   =   0   'False
          EndProperty
          Height          =   285
          Left            =   1515
          TabIndex        =   1
          Top             =   1350
          Width           =   75
       End
    End
    Attribute VB_Name = "Form1"
    Attribute VB_GlobalNameSpace = False
    Attribute VB_Creatable = False
    Attribute VB_PredeclaredId = True
    Attribute VB_Exposed = False
    Option ExplicitPrivate Sub Command1_MouseDown(Button As Integer, Shift As Integer, x As Single, Y As Single)    Label1 = ""
        Label2 = ""End SubPrivate Sub Command1_Click()
        
        Label1 = GetCpuName() & " CPU"
        Label2 = "You have a" & IIf(InStr("AEIOU", Left$(Label1, 1)), "n", "")End Sub
    ------------------------------end---------------------------------下面是modu1e.bas的源代码----------------------module1.bas的源文件--------------------------
    Option Explicit
    '
    'This shows how to incorporate machine code into VB
    '''''''''''''''''''''''''''''''''''''''''''''''''''
    'The example fills the array with a few machine instructions and then copies
    'them to a procedure address. The modified procedure is then called thru
    'CallWindowProc. The result of this specific machine code is your CPU Vendor Name.
    '
    '##########################################################################
    'Apparently it gets a Stack Pointer Error, but I don't know why; if anybody
    'can fix that please let me know...                          [email protected]
    'The Error is not present in the native compiled version; so I think it got
    'something to do with the P-Code Calling Convention (strange though)...
    '##########################################################################
    '
    'Sub Dummy serves to reserve some space to copy the machine instructions into.
    '
    '
    'Tested on Intel and AMD CPU's (uncompiled and compiled)
    '
    '
    Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpvDest As Any, lpvSource As Any, ByVal cbCopy As Long)
    Private x As LongPublic Function GetCpuName() As String
      
      Dim MachineCode(0 To 35)  As Byte
      Dim VarAddr               As Long
      Dim FunctAddr             As Long
      Dim EAX                   As Long
      Dim CPUName(1 To 12)      As Byte
      
      'set up machine code
        
        MachineCode(0) = &H55    'push ebp
        
        MachineCode(1) = &H8B    'move ebp,esp
        MachineCode(2) = &HEC
        
        MachineCode(3) = &H57    'push edi
        
        MachineCode(4) = &H52    'push edx
        
        MachineCode(5) = &H51    'push ecx
        
        MachineCode(6) = &H53    'push ebx
        
        MachineCode(7) = &H8B    'move eax,dword ptr [ebp+8]
        MachineCode(8) = &H45
        MachineCode(9) = &H8
        
        MachineCode(10) = &HF    'cpuid
        MachineCode(11) = &HA2
        
        MachineCode(12) = &H8B   'mov edi,dword ptr [ebp+12]
        MachineCode(13) = &H7D
        MachineCode(14) = &HC
        
        MachineCode(15) = &H89   'move dword ptr [edi],ebx
        MachineCode(16) = &H1F
        
        MachineCode(17) = &H8B   'mov edi,dword ptr [ebp+16]
        MachineCode(18) = &H7D
        MachineCode(19) = &H10
        
        MachineCode(20) = &H89   'move dword ptr [edi],ecx
        MachineCode(21) = &HF
        
        MachineCode(22) = &H8B   'mov edi,dword ptr [ebp+20]
        MachineCode(23) = &H7D
        MachineCode(24) = &H14
        
        MachineCode(25) = &H89   'move dword ptr [edi],edx
        MachineCode(26) = &H17
        
        MachineCode(27) = &H58   'pop ebx    MachineCode(28) = &H59   'pop ecx    MachineCode(29) = &H5A   'pop edx    MachineCode(30) = &H55   'pop edi
        
        MachineCode(31) = &HC9   'leave    MachineCode(32) = &HC2   'ret 16     I tried everything from 0 to 24
        MachineCode(33) = &H10   '           but all produce the stack error
        MachineCode(34) = &H0
        
        'tell cpuid what we want
        EAX = 0
        
        'get address of Machine Code
        VarAddr = VarPtr(MachineCode(0))
        
        'get address of Sub Dummy
        FunctAddr = GetAddress(AddressOf Dummy)
        
        'copy the Machine Code to where it can be called
        CopyMemory ByVal FunctAddr, ByVal VarAddr, 35 '35 bytes machine code
        
        'call it
        On Error Resume Next 'apparently it gets a stack pointer error when in P-Code but i dont know why
          CallWindowProc FunctAddr, EAX, VarPtr(CPUName(1)), VarPtr(CPUName(9)), VarPtr(CPUName(5))
          'Debug.Print Err; Err.Description
          'MsgBox Err & Err.Description
        On Error GoTo 0
        
        GetCpuName = StrConv(CPUName(), vbUnicode) 'UnicodeName
        
    End FunctionPrivate Function GetAddress(Address As Long) As Long    GetAddress = AddressEnd FunctionPrivate Sub Dummy()  'the code below just reserves some space to copy the machine code into
      'it is never executed    x = 0
        x = 1
        x = 2
        x = 3
        x = 4
        x = 5
        x = 6
        x = 7
        x = 8
        x = 9
        x = 10
        x = 0
        x = 1
        x = 2
        x = 3
        x = 4
        x = 5
        x = 6
        x = 7
        x = 8
        x = 9
        x = 10
       
    End Sub
    ------------------------------end--------------------------------------
    摘自《vb情报站》 http://www.vbprobe.com/tips/showdoc.asp?detail_id=2064
      

  3.   

    上面代码是 dyx(天火) ( ) 老兄贴在CSDN的但其实实现起来很困难,不是不得已,放弃该想法。hehe
      

  4.   

    一般来说,VB和VC共同编程有3种方式:一种是VC生成DLL,在VB中调用DLL;一种是VC生成ActiveX控件(.ocx),在VB中插入;还有一种是在VC中生成ActiveX Automation服务器,在VB中调用。相对而言,第一种方法对VC编程者的要求最低,但要求你的伙伴进行配合,我推荐这种方法。 
        先说说VC++的编程。首先在VC++中生成Win32 DLL工程。在这个工程中添加几个函数供VB用户调用。一个DLL中的函数要想被VB调用,必须满足两个条件:一是调用方式为stdcall,另一个是必须是export的。要做到第一条,只须在函数声明前加上__stdcall关键字。如: 
        short __stdcall sample(short nLen, short *buffer) 
        要做到第二条,需要在*.def文件中加上如下的几行: 
        EXPORTS 
         sample @1 
        这里的sample是你要在VB中调用的函数名,@1表示该函数在DLL中的编号,每个函数都不一样。注意这里的函数名是区分大小写的。至于你说的需要传递大量数据,可以这样做,在VB中用一个数组存放数据,然后将该数组的大小和地址传给VC(至于如何在VB中编程我会在下面介绍)。就象上面的例子,nLen是数组大小,buffer是数组地址,有了这两条,你可以象使用VC的数组一样进行处理了。至于输出图形,可以生成WMF或BMP格式,让VB调用。不过,我认为也可以直接输出到视窗,只要VB将窗口的句柄hWnd和hDC以及视窗的绘图位置(VB和VC采用的坐标系必须一致才行)传给VC就行了。而VB的AutoRedraw属性必须为False,在Paint事件中调用VC的绘图程序。 
        再谈谈VB的编程。VB调用DLL的方法和调用Windows API的方法是一样的,一般在VB的书中有介绍。对于上面一个例子,先要声明VC函数: 
        Declare Function sample Lib "mydll.dll" (ByVal nLen As Integer, buffer As Integer) As Integer 
        这里mydll.dll是你的dll的名字。你可能已经注意到了两个参数的声明有所不同,第一个参数加上了ByVal。规则是这样的:如果在VC中某个参数声明为指针和数组,就不加ByVal,否则都要加上ByVal。在VB中调用这个函数采用这样的语法: 
        sample 10, a(0) 
        这里的a()数组是用来存放数据的,10为数组长度,这里的第二个参数不能是a(),而必须是要传递的数据中的第一个。这是VB编程的关键。 
        下面在说几个可能遇到的问题。一个问题是VB可能报告找不到dll,你可以把dll放到system目录下,并确保VB的Declare语句正确。另一个问题是VB报告找不到需要的函数,这通常是因为在VC中*.def文件没设置。第三种情况是VB告诉不能进行转换,这可能是在VC中没有加上__stdcall关键字,也可能是VB和VC的参数类型不一致,注意在VC中int是4个字节(相当于VB的Long),而VB的Integer只有2个字节。必须保证VB和VC的参数个数相同,所占字节数也一致。最后一个要注意的问题是VC中绝对不能出现数组越界的情况,否则会导致VB程序崩溃。 
        总的来说,你和你的伙伴需要一些时间来进行协调和摸索,但这种方法绝对可行,也不难掌握。 
      

  5.   

    为什么要嵌入C++的代码呢?把C++编译成DLL,要用的时候直接调用不行吗?