教你用Windows API 写一个Thread类(不使用static哦)------(3)

22 篇文章 0 订阅
14 篇文章 0 订阅

        在这文章里面,我主要解释class里面的函数调用原理,首先给出测试代码如下:

class	CBase{
public:
	void	Hello(){
	}
};

int main(){
	CBase	base;
	base.Hello();
}


        同样地,按照前面文章讲解的方法,汇编得到以下main.asm,如下:

; Listing generated by Microsoft (R) Optimizing Compiler Version 16.00.30319.01 

	TITLE	E:\bossjue\main.cpp
	.686P
	.XMM
	include listing.inc
	.model	flat

INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES

PUBLIC	?Hello@CBase@@QAEXXZ				; CBase::Hello
PUBLIC	_main
; Function compile flags: /Odtp
_TEXT	SEGMENT
_base$ = -1						; size = 1
_main	PROC
; File e:\bossjue\main.cpp
; Line 7
	push	ebp
	mov	ebp, esp
	push	ecx
; Line 9
	lea	ecx, DWORD PTR _base$[ebp]
	call	?Hello@CBase@@QAEXXZ			; CBase::Hello
; Line 10
	xor	eax, eax
	mov	esp, ebp
	pop	ebp
	ret	0
_main	ENDP
; Function compile flags: /Odtp
_TEXT	ENDS
;	COMDAT ?Hello@CBase@@QAEXXZ
_TEXT	SEGMENT
_this$ = -4						; size = 4
?Hello@CBase@@QAEXXZ PROC				; CBase::Hello, COMDAT
; _this$ = ecx
; Line 3
	push	ebp
	mov	ebp, esp
	push	ecx
	mov	DWORD PTR _this$[ebp], ecx
; Line 4
	mov	esp, ebp
	pop	ebp
	ret	0
?Hello@CBase@@QAEXXZ ENDP				; CBase::Hello
_TEXT	ENDS
END


        对比上面我汇编汇编的非类的函数调用,你可以看到,无非是多了一个mov ecx, this的操作(等价的代码),其意思是把this复制给ecx,再调用函数,因此我们可以猜测,VS上的C++类函数调用是用ecx传递this指针(对stack没影响哦),我们写出如下测试代码,可以看到成功运行:

#include <iostream>
using namespace std;
class	CBase{
public:
	CBase(int iValue):m_iValue(iValue){}
public:
	void	Hello(){
		cout<<m_iValue<<endl;
	}
private:
	int	m_iValue;
};

int main(){
	CBase	base(100);
	typedef	  void	(CBase::*FunPtr)();
	FunPtr	FunAddr=	&CBase::Hello;
	__asm{
		lea	ecx, base
		call	FunAddr
	}
}


 

        但是,如果我们去掉lea ecx, base的话,会看到运行错误哦, 说明了vs是用ecx传递this指针的。那么,我们可以想,既然VS是用ecx传递this指针,我们就可以把类的成员函数做为Thread函数了,只是在一个适当的时候让ecx等于this,对吧,问题是这个适当的时候是什么时候,还有,怎么样让ecx传递this呢?这是下一节中讲的内容。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在.NET 6.0中,可以使用Windows API来调用摄像头进行拍照和录制视频。具体步骤如下: 1. 引用相关命名空间:需要使用Windows API进行摄像头的调用,需要在代码文件中添加以下命名空间: ```csharp using System.Runtime.InteropServices; using System.Diagnostics; using System.Windows.Forms; ``` 2. 调用摄像头进行拍照:使用Windows API中的SendMessage方法指定命令来调用摄像头,如下所示: ```csharp [DllImport("user32.dll", EntryPoint = "SendMessage")] public static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam); const uint WM_CAP_START = 0x400; const uint WM_CAP_DRIVER_CONNECT = WM_CAP_START + 10; const uint WM_CAP_DRIVER_DISCONNECT = WM_CAP_START + 11; const uint WM_CAP_SAVEDIB = WM_CAP_START + 25; const int IDOK = 1; public void TakePhoto() { ProcessStartInfo startInfo = new ProcessStartInfo("C:\\Windows\\System32\\amcap.exe"); // 打开摄像头软件 Process.Start(startInfo); IntPtr hWnd = IntPtr.Zero; while (hWnd.ToInt32() == 0) { hWnd = FindWindow(null, "AMCap"); // 查找摄像头软件的窗口句柄 Thread.Sleep(100); } SendMessage(hWnd.ToInt32(), WM_CAP_DRIVER_CONNECT, 0, 0); // 连接摄像头 SendMessage(hWnd.ToInt32(), WM_CAP_SAVEDIB, 0, 0); // 拍照 SendMessage(hWnd.ToInt32(), WM_CAP_DRIVER_DISCONNECT, 0, 0); // 断开连接摄像头 } ``` 3. 调用摄像头进行录制视频:同样是使用Windows API中的SendMessage方法指定命令来调用摄像头,如下所示: ```csharp [DllImport("user32.dll", EntryPoint = "SendMessage")] public static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam); const uint WM_CAP_START = 0x400; const uint WM_CAP_DRIVER_CONNECT = WM_CAP_START + 10; const uint WM_CAP_DRIVER_DISCONNECT = WM_CAP_START + 11; const uint WM_CAP_SET_PREVIEW = WM_CAP_START + 50; const uint WM_CAP_SET_PREVIEWRATE = WM_CAP_START + 52; const uint WM_CAP_SAVEDIB = WM_CAP_START + 25; const int IDOK = 1; public void RecordVideo() { ProcessStartInfo startInfo = new ProcessStartInfo("C:\\Windows\\System32\\amcap.exe"); // 打开摄像头软件 Process.Start(startInfo); IntPtr hWnd = IntPtr.Zero; while (hWnd.ToInt32() == 0) { hWnd = FindWindow(null, "AMCap"); // 查找摄像头软件的窗口句柄 Thread.Sleep(100); } SendMessage(hWnd.ToInt32(), WM_CAP_DRIVER_CONNECT, 0, 0); // 连接摄像头 SendMessage(hWnd.ToInt32(), WM_CAP_SET_PREVIEW, 0, 0); // 设置预览 SendMessage(hWnd.ToInt32(), WM_CAP_SET_PREVIEWRATE, 66, 0); // 设置预览帧率 string fileName = "C:\\video.avi"; if (File.Exists(fileName)) File.Delete(fileName); SendMessage(hWnd.ToInt32(), WM_CAP_SAVEDIB, 0, fileName); // 开始录制 MessageBox.Show("按OK停止录制", "提示", MessageBoxButtons.OK); SendMessage(hWnd.ToInt32(), WM_CAP_SAVEDIB, 0, 0); // 停止录制 SendMessage(hWnd.ToInt32(), WM_CAP_DRIVER_DISCONNECT, 0, 0); // 断开连接摄像头 } ``` 需要注意的是,这两个方法都是在Windows环境下调用摄像头软件进行实现的,因此需要保证在调用的计算机上已经安装了能够调用摄像头的摄像头软件。如果想要在跨平台的环境中使用摄像头,可能需要使用其他的第三方库或者API进行实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值