Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 文本); WriteLine(“获取地址:{0}”,exampleStringPtr.ToInt32()); var lockedPtr=WinAPI.GlobalLock(例如stringptr); var s=Marshal.PtrToStringUni(lockedPtr); GlobalUnlock(lockedPtr); WriteLine(“获取的字符串:{0}”,s); WinAPI.CloseClipboard(); }_C#_String_Winapi_Clipboard - Fatal编程技术网

C# 文本); WriteLine(“获取地址:{0}”,exampleStringPtr.ToInt32()); var lockedPtr=WinAPI.GlobalLock(例如stringptr); var s=Marshal.PtrToStringUni(lockedPtr); GlobalUnlock(lockedPtr); WriteLine(“获取的字符串:{0}”,s); WinAPI.CloseClipboard(); }

C# 文本); WriteLine(“获取地址:{0}”,exampleStringPtr.ToInt32()); var lockedPtr=WinAPI.GlobalLock(例如stringptr); var s=Marshal.PtrToStringUni(lockedPtr); GlobalUnlock(lockedPtr); WriteLine(“获取的字符串:{0}”,s); WinAPI.CloseClipboard(); },c#,string,winapi,clipboard,C#,String,Winapi,Clipboard,我运行程序,暂停它,并通过WinDbg分析内存。然后我制作结果截图并提供给你。因此,我的测试和截图显示: 1.)内存中有一个源对象的多个副本 2.)如果在关闭剪贴板之前更改给定给SetClipboardData调用的源内存,则在再次打开剪贴板之后,剪贴板甚至在源地址上恢复源对象 不是吗?有人能解释一下这些条款是真是假吗 更新2:好的。。我正在重写C++的第三次测试。在这里: #include "stdafx.h" #include "windows.h" #include "conio.h"

我运行程序,暂停它,并通过WinDbg分析内存。然后我制作结果截图并提供给你。因此,我的测试和截图显示:

1.)内存中有一个源对象的多个副本 2.)如果在关闭剪贴板之前更改给定给SetClipboardData调用的源内存,则在再次打开剪贴板之后,剪贴板甚至在源地址上恢复源对象

不是吗?有人能解释一下这些条款是真是假吗

更新2:好的。。我正在重写C++的第三次测试。在这里:

#include "stdafx.h"
#include "windows.h"
#include "conio.h"

int main()
{
HWND owner = GetConsoleWindow();

//1.) Copying string to clipboard
if (OpenClipboard(owner))
{
    EmptyClipboard();

    //WCHAR *str = L"Loooong string example";
    char *str = "Loooooooong string Example";

    int cch = strlen(str);

    char* strptr = (char*)GlobalAlloc(GMEM_MOVEABLE, (cch + 1));

    printf("setting (segment??) address: %X \n", strptr);

    LPVOID lockedPtr = GlobalLock(strptr);
    printf("locked setting address: %X \n", lockedPtr);

    // copy
    memcpy(lockedPtr, str, cch);

    GlobalUnlock(strptr);

    // set to clipboard
    SetClipboardData(CF_TEXT, strptr);

    //2.) Change string while clipboard isn't closed - replace first 10 characters on one any symbol 
    lockedPtr = GlobalLock(strptr);
    for (int i = 0; i < 10; i++)
    {
        ((char*)lockedPtr)[i] = 50;
    }
    GlobalUnlock(strptr);

    //3.) Obtain string and make sure that string was changed
    lockedPtr = GlobalLock(strptr);
    printf("changed string: %s \n", lockedPtr);
    GlobalUnlock(strptr);

    //4.) Get this string from clipboard and make sure that clipboard was changed
    strptr = (char*)GetClipboardData(CF_TEXT);

    printf("getting address: %X \n", strptr);

    lockedPtr = GlobalLock(strptr);

    printf("locked getting address: %X \n", lockedPtr);

    printf("obtained string: %s \n", (char*)lockedPtr );

    GlobalUnlock(strptr);

    CloseClipboard();

}

printf("\n-------Close and open clipboard------------------\n");

//5.) Getting string from clipboard
for (int i = 0; i < 10; i++)
{
    //Sleep(1000);
    if (OpenClipboard(owner))
    {
        HANDLE exampleStringPtr = GetClipboardData(CF_TEXT);

        printf("getting address: %X \n", exampleStringPtr);

        char* lockedPtr = (char*)GlobalLock(exampleStringPtr);

        printf("locked getting address: %X \n", lockedPtr);
        printf("obtained string: %s \n", lockedPtr);

        GlobalUnlock(exampleStringPtr);

        CloseClipboard();
    }
}

getch();
return 0;
} 
#包括“stdafx.h”
#包括“windows.h”
#包括“conio.h”
int main()
{
HWND owner=GetConsoleWindow();
//1.)将字符串复制到剪贴板
如果(打开剪贴板(所有者))
{
清空电路板();
//WCHAR*str=L“looong字符串示例”;
char*str=“looooong字符串示例”;
int-cch=strlen(str);
char*strprtr=(char*)GlobalAlloc(GMEM_可移动,(cch+1));
printf(“设置(段??)地址:%X\n”,strptr);
LPVOID lockedPtr=GlobalLock(strprtr);
printf(“锁定的设置地址:%X\n”,lockedPtr);
//抄袭
memcpy(锁定PTR、str、cch);
GlobalUnlock(strprtr);
//设置为剪贴板
SetClipboardData(CF_TEXT,strprtr);
//2.)在剪贴板未关闭时更改字符串-替换任何符号上的前10个字符
锁定PTR=全局锁定(strptr);
对于(int i=0;i<10;i++)
{
((char*)lockedPtr)[i]=50;
}
GlobalUnlock(strprtr);
//3.)获取字符串并确保字符串已更改
锁定PTR=全局锁定(strptr);
printf(“更改的字符串:%s\n”,lockedPtr);
GlobalUnlock(strprtr);
//4.)从剪贴板获取此字符串,并确保剪贴板已更改
strprpr=(char*)GetClipboardData(CF_TEXT);
printf(“获取地址:%X\n”,strprtr);
锁定PTR=全局锁定(strptr);
printf(“锁定的获取地址:%X\n”,lockedPtr);
printf(“获取的字符串:%s\n”,(char*)lockedPtr);
GlobalUnlock(strprtr);
CloseClipboard();
}
printf(“\n-------关闭并打开剪贴板-----------------\n”);
//5.)从剪贴板获取字符串
对于(int i=0;i<10;i++)
{
//睡眠(1000);
如果(打开剪贴板(所有者))
{
HANDLE exampleStringPtr=GetClipboardData(CF_TEXT);
printf(“获取地址:%X\n”,exampleStringPtr);
char*lockedPtr=(char*)GlobalLock(例如stringptr);
printf(“锁定的获取地址:%X\n”,lockedPtr);
printf(“获取的字符串:%s\n”,lockedPtr);
GlobalUnlock(示例StringPtr);
CloseClipboard();
}
}
getch();
返回0;
} 
事实上,现在当我调用GetClipboardData时,我总是获得指向数据的相同指针。但有时它和我放入剪贴板的第一个字符串的锁定指针不同

虽然我在C++上写了这个测试,但我仍然有着早期写作的效果。

若我在调用SetClipboardData后更改了源内存块,然后尝试调用GetClipboardData,我将获得更改后的内存块。但当我关闭这个剪贴板,然后再次打开它时,我更改的内存块被一些信息覆盖了,我不知道,当我调用GetClipboardData时,内存块被恢复到初始状态,就好像我没有更改它一样

从哪里剪贴板“知道”如何恢复这个块,如果它没有它的副本,我改变了源块


我录制了一个小屏幕,显示内存在什么时候恢复了

SetClipboardData
将数据复制到给定的全局句柄中。关闭剪贴板后,应释放全局句柄(而不是在此之前)
GetClipboardData
返回(内部)内存句柄;您应该将此句柄视为只读缓冲区。

的文档非常清楚地表明,它不会复制您提供的数据-相反,剪贴板拥有数据句柄,尽管在关闭剪贴板之前您仍然可以从中读取,但一旦
SetClipboardData()
呼叫已成功

一旦您关闭了剪贴板,您就不再拥有剪贴板,并且数据对象根本无法安全使用,即使用于读取,因为另一个进程可能已经更改了剪贴板的内容。您在关闭剪贴板后修改数据的测试是靠运气完成的,而不是因为它们本应如此

如果SetClipboardData成功,则系统拥有由 hMem参数。应用程序可能无法写入或释放数据 一旦所有权转移到系统,但它可以锁定和 读取数据,直到调用CloseClipboard函数。(修订) 必须先解锁内存,然后才能关闭剪贴板。)

编辑:因为你似乎对资源所有权的概念和未定义的行为有困难,也许这个类比会有所帮助

// allocate 1 byte of memory
char* ptr = malloc(sizeof(char));
// set the byte to the letter A
*ptr = 'A'; 
// free the memory
free(ptr);
// set the byte to B
*ptr = 'B';
// verify that the byte is set to B
printf("byte contains %c\n", *ptr);
// allocate another byte of memory
char* ptr2 = malloc(sizeof(char));
// are they the same byte? maybe
printf("byte contains %c - first was %lx, second is %lx\n", *ptr2, ptr, ptr2);
我希望你会发现这个代码是完全错误的。我们分配内存,写入它,释放它,然后,我们写入它并再次读取它。然而,如果您编译并运行这段代码,它很有可能会工作。第二次分配很有可能返回与第一次分配相同的地址。发生什么事了

这称为未定义的行为。语言没有定义在这种情况下会发生什么。当你释放内存时,你不再拥有它,你不能向它写入或读取它。如果它起作用,或者看起来起作用,那只是巧合,仅此而已。没有人能保证它会一直持续下去
        //1.) Copying string to clipboard
        if (WinAPI.OpenClipboard(owner))
        {
            WinAPI.EmptyClipboard();

            IntPtr exampleStringPtr = Marshal.StringToHGlobalUni("Loooooooooooonng String Example");

            Console.WriteLine("setting address: {0}", exampleStringPtr.ToInt32());

            WinAPI.SetClipboardData(WinAPI.CF_UNICODETEXT, exampleStringPtr);

            //2.) Change string while clipboard isn't closed - replace first 10 characters on one any symbol 
            for (int i = 0; i < 10; i++)
            {
                Marshal.WriteByte(exampleStringPtr + i, 50);
            }

            //3.) Obtain string and make sure that string was changed
            Console.WriteLine("changed string: {0}", Marshal.PtrToStringUni(exampleStringPtr));

            //4.) Get this string from clipboard and make sure that clipboard was changed
            exampleStringPtr = WinAPI.GetClipboardData(WinAPI.CF_UNICODETEXT);

            Console.WriteLine("getting address of changed string: {0}", exampleStringPtr.ToInt32());

            var lockedPtr = WinAPI.GlobalLock(exampleStringPtr);

            var s = Marshal.PtrToStringUni(exampleStringPtr);
            WinAPI.GlobalUnlock(lockedPtr);

            Console.WriteLine("obtained string: {0}", s);

            WinAPI.CloseClipboard();

        }
            Console.WriteLine("\n-------Close and open clipboard------------------\n");

            //5.) Getting string from clipboard
            for (int i = 0; i < 100; i++)
                if (WinAPI.OpenClipboard(owner))
                {
                    IntPtr exampleStringPtr = WinAPI.GetClipboardData(WinAPI.CF_UNICODETEXT);

                    Console.WriteLine("getting address: {0}", exampleStringPtr.ToInt32());

                    var lockedPtr = WinAPI.GlobalLock(exampleStringPtr);

                    var s = Marshal.PtrToStringUni(lockedPtr);

                    WinAPI.GlobalUnlock(lockedPtr);

                    Console.WriteLine("obtained string: {0}", s);

                    WinAPI.CloseClipboard();
                }
#include "stdafx.h"
#include "windows.h"
#include "conio.h"

int main()
{
HWND owner = GetConsoleWindow();

//1.) Copying string to clipboard
if (OpenClipboard(owner))
{
    EmptyClipboard();

    //WCHAR *str = L"Loooong string example";
    char *str = "Loooooooong string Example";

    int cch = strlen(str);

    char* strptr = (char*)GlobalAlloc(GMEM_MOVEABLE, (cch + 1));

    printf("setting (segment??) address: %X \n", strptr);

    LPVOID lockedPtr = GlobalLock(strptr);
    printf("locked setting address: %X \n", lockedPtr);

    // copy
    memcpy(lockedPtr, str, cch);

    GlobalUnlock(strptr);

    // set to clipboard
    SetClipboardData(CF_TEXT, strptr);

    //2.) Change string while clipboard isn't closed - replace first 10 characters on one any symbol 
    lockedPtr = GlobalLock(strptr);
    for (int i = 0; i < 10; i++)
    {
        ((char*)lockedPtr)[i] = 50;
    }
    GlobalUnlock(strptr);

    //3.) Obtain string and make sure that string was changed
    lockedPtr = GlobalLock(strptr);
    printf("changed string: %s \n", lockedPtr);
    GlobalUnlock(strptr);

    //4.) Get this string from clipboard and make sure that clipboard was changed
    strptr = (char*)GetClipboardData(CF_TEXT);

    printf("getting address: %X \n", strptr);

    lockedPtr = GlobalLock(strptr);

    printf("locked getting address: %X \n", lockedPtr);

    printf("obtained string: %s \n", (char*)lockedPtr );

    GlobalUnlock(strptr);

    CloseClipboard();

}

printf("\n-------Close and open clipboard------------------\n");

//5.) Getting string from clipboard
for (int i = 0; i < 10; i++)
{
    //Sleep(1000);
    if (OpenClipboard(owner))
    {
        HANDLE exampleStringPtr = GetClipboardData(CF_TEXT);

        printf("getting address: %X \n", exampleStringPtr);

        char* lockedPtr = (char*)GlobalLock(exampleStringPtr);

        printf("locked getting address: %X \n", lockedPtr);
        printf("obtained string: %s \n", lockedPtr);

        GlobalUnlock(exampleStringPtr);

        CloseClipboard();
    }
}

getch();
return 0;
} 
// allocate 1 byte of memory
char* ptr = malloc(sizeof(char));
// set the byte to the letter A
*ptr = 'A'; 
// free the memory
free(ptr);
// set the byte to B
*ptr = 'B';
// verify that the byte is set to B
printf("byte contains %c\n", *ptr);
// allocate another byte of memory
char* ptr2 = malloc(sizeof(char));
// are they the same byte? maybe
printf("byte contains %c - first was %lx, second is %lx\n", *ptr2, ptr, ptr2);