首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

如何在纯C中使用DispCallFunc调用IStream::SetSize(0)

在纯C中使用DispCallFunc调用IStream::SetSize(0)的方法如下:

首先,需要引入相关的头文件和库文件:

代码语言:c
复制
#include <windows.h>
#include <objbase.h>
#include <stdio.h>

然后,定义相关的接口和函数指针:

代码语言:c
复制
typedef struct _IStreamVtbl {
    HRESULT(STDMETHODCALLTYPE *QueryInterface)(IStream *This, REFIID riid, void **ppvObject);
    ULONG(STDMETHODCALLTYPE *AddRef)(IStream *This);
    ULONG(STDMETHODCALLTYPE *Release)(IStream *This);
    HRESULT(STDMETHODCALLTYPE *Read)(IStream *This, void *pv, ULONG cb, ULONG *pcbRead);
    HRESULT(STDMETHODCALLTYPE *Write)(IStream *This, const void *pv, ULONG cb, ULONG *pcbWritten);
    HRESULT(STDMETHODCALLTYPE *Seek)(IStream *This, LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition);
    HRESULT(STDMETHODCALLTYPE *SetSize)(IStream *This, ULARGE_INTEGER libNewSize);
    HRESULT(STDMETHODCALLTYPE *CopyTo)(IStream *This, IStream *pstm, ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten);
    HRESULT(STDMETHODCALLTYPE *Commit)(IStream *This, DWORD grfCommitFlags);
    HRESULT(STDMETHODCALLTYPE *Revert)(IStream *This);
    HRESULT(STDMETHODCALLTYPE *LockRegion)(IStream *This, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType);
    HRESULT(STDMETHODCALLTYPE *UnlockRegion)(IStream *This, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType);
    HRESULT(STDMETHODCALLTYPE *Stat)(IStream *This, STATSTG *pstatstg, DWORD grfStatFlag);
    HRESULT(STDMETHODCALLTYPE *Clone)(IStream *This, IStream **ppstm);
} IStreamVtbl;

typedef struct _IStream {
    IStreamVtbl *lpVtbl;
} IStream;

typedef HRESULT(STDMETHODCALLTYPE *DispCallFunc)(void *pvInstance, ULONG oVft, CC *cc, VARTYPE vtReturn, UINT cActuals, VARTYPE *prgvt, VARIANTARG **prgpvarg, VARIANT *pvargResult);

接下来,实现调用函数:

代码语言:c
复制
void CallIStreamSetSize()
{
    HMODULE hOle32 = LoadLibraryA("ole32.dll");
    if (hOle32 == NULL) {
        printf("Failed to load ole32.dll\n");
        return;
    }

    DispCallFunc pDispCallFunc = (DispCallFunc)GetProcAddress(hOle32, "DispCallFunc");
    if (pDispCallFunc == NULL) {
        printf("Failed to get address of DispCallFunc\n");
        FreeLibrary(hOle32);
        return;
    }

    IStream *pStream = NULL;
    HRESULT hr = CoCreateInstance(&CLSID_NULL, NULL, CLSCTX_INPROC_SERVER, &IID_IStream, (void **)&pStream);
    if (FAILED(hr)) {
        printf("Failed to create IStream instance\n");
        FreeLibrary(hOle32);
        return;
    }

    IStreamVtbl *pStreamVtbl = pStream->lpVtbl;
    ULONG oVft = (ULONG)((char *)&pStreamVtbl->SetSize - (char *)pStreamVtbl);
    CC cc = CC_STDCALL;
    VARTYPE vtReturn = VT_HRESULT;
    UINT cActuals = 2;
    VARTYPE rgvt[2] = { VT_UNKNOWN, VT_UI8 };
    VARIANTARG pvarg[2] = { 0 };
    pvarg[0].vt = VT_UNKNOWN;
    pvarg[0].punkVal = NULL;
    pvarg[1].vt = VT_UI8;
    pvarg[1].ullVal = 0;

    VARIANT vResult;
    VariantInit(&vResult);

    hr = pDispCallFunc(pStream, oVft, &cc, vtReturn, cActuals, rgvt, &pvarg, &vResult);
    if (FAILED(hr)) {
        printf("Failed to call IStream::SetSize\n");
    } else {
        printf("IStream::SetSize called successfully\n");
    }

    VariantClear(&vResult);
    pStream->lpVtbl->Release(pStream);
    FreeLibrary(hOle32);
}

最后,在主函数中调用该函数:

代码语言:c
复制
int main()
{
    CoInitialize(NULL);
    CallIStreamSetSize();
    CoUninitialize();
    return 0;
}

这样就可以在纯C中使用DispCallFunc调用IStream::SetSize(0)了。

请注意,以上代码仅供参考,实际使用时需要根据具体情况进行适当的修改和错误处理。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

C++ 重载运算符 继承 多态 (超详细)

用非类A类型的值为类A的对象赋值时(当然,这种情况下我们可以不提供相应的赋值运算符重载函数,而只提供相应的构造函数,更有重载函数会优先调用重载后的赋值运算符)。...,在程序需要使用基类对象的地方都可以用公有派生类的对象代替。...+虚函数 1.虚函数是在基类声明的虚函数,它在基类没有定义,但要求任何派生类都要定义自己的实现方法。...在基类实现虚函数的方法是在函数原型后加“=0” virtual void funtion()=0 1、为了方便使用多态特性,我们常常需要在基类定义虚拟函数。...{ } } 为了解决上述问题,引入了虚函数的概念 Class animals { virtual void mingjiao()=0; } 则编译器要求在派生类必须予以重写以实现多态性。

1.1K21

服务器是干嘛的

今天有个网友问我如何编写一个DCOM服务器,可以在C#的客户端调用。看起来还是有很多人在用COM技术,趁这个机会,就把DCOM和C#之间的互操作好好讲讲。...道理很简单,C#后于C++ DCOM技术出现,作为前辈的DCOM技术不可能预知采用什么技术支持小辈C#。在C#里面使用DCOM的服务,跟 C++的COM客户端的步骤是一样的,即: 1....每次C#程序调用这个类的抽象函数的时候,CLR会自动将调用转换成对应的COM调用。...\Debug\sserver.exe C++客户端 使用下面的C++ DCOM客户端程序来验证一下DCOM服务器: 1....获取已经激活的DCOM对象的指针,接着再是查询对应的COM接口,本文的例子里是IStream接口,这样在C#程序里面才能调用

7.2K31
  • C++核心编程学习

    :用来修饰形参,防止误操作 三、函数 1、函数默认参数 int func(int a, int b = 100, int c = 100)之后调用的时候可以使用以下调用方式:func(10), func...,才是合法int func(int a = 10, int b, int c)是不合法的!!!...c1); friend istream& operator >>(istream& is, const Complex& c1); }; inline Complex operator +...虚函数:virtual 返回值 函数名(参数列表) = 0; 只要有一个虚函数的类,被称为抽象类; 抽象类特点:无法实例化对象, 抽象类的子类必须要重写父类虚函数,否则子类也为抽象类; (5...)虚析构和虚析构 多态使用时, 如果子类中有属性开辟到堆区, 那么父类指针在释放时无法调用到子类的析构代码;(即:子类的析构函数不会被调用) 上面问题解决:将父类的析构函数改为虚析构或者虚析构即可

    38310

    从零开始学C++之STL(十):迭代器适配器{(插入迭代器back_insert_iterator)、IO流迭代器(istream_iterator、ostream_iterator)}

    程序调用了copy  函数,回顾copy 源码,主要是以下代码: for (; _First !...故如vector 是没有实现push_front 的,不能使用front_insert_iterator ,而list 和 deque 是可以使用的。...类有两个成员,一个是输入流对象指针,一个是输入的值, istream_iterator(cin)  调用构造函数,初始化_Myistr,且通过函数_Getval() 初始化_Myval...= 0) *_Myostr << _Mydelim; 即判断如果还有传入字符串,则在输出元素值之后,还伴随着字符串的输出。所以示例代码的输出是伴随着空格的。...参考: C++ primer 第四版 Effective C++ 3rd C++编程规范

    1K00

    C++航海王:追寻罗杰的编程之路】C++的IO流

    C++流是指信息从外部输入设备(键盘)向计算机内部(内存)输入和从内存向外部输出设备(显示器)输出的过程。这种输入输出的过程被形象的比喻为“流”。 它的特性是:有序连续、具有方向性。...使用cin进行标准输入即数据通过键盘输入到程序,同时C++标准库还提供了cerr用来进行标准错误的输出,以及clog进行日志的输出,从上图可以看出,cout、cerr、clog是ostream类的三个不同的对象...istream& operator>> (int& val); explicit operator bool() const; 实际上,我们看到使用while(cin >> i)去流中提取对象数据时,调用的是...operator>>,返回值是istream类型的对象,那么这里可以做逻辑条件值,源自于istream的对象又调用了operator bool,operator bool调用时如果接收流失败,或者有结束标志...} 在C++,可以使用stringstream类对象来避开此问题。

    10110

    C++】操作符重载的应用—— 重现

    & operator>>(istream& in, Date& d); .c文件部分: ostream& operator<<(ostream& out, const Date& d) { out...=(const Date& x) const; .c文件实现: PS:在函数实现过程可以使用技巧"复用" (多个函数只需要复用一个定义即可,具体代码) bool Date::operator==(const...YY的C++知识合集博客,关于const的解读) PS:const加在后面表示const Date* this ;表明在该成员函数不能对类的任何成员进行修改,而+=,-=是要实现对类内成员的改变,因此不能加...前置的是【先赋值后使用】:返回的是本身(Date&接收)(引用提高效率) 后置的是【先使用后赋值】:返回的是临时变量(Date接收)(不用引用,因为临时变量出作用域即销毁,引用会变成野引用) 2.如何在定义与声明中区分前后置...& operator>>(istream& in, Date& d); .c文件: #include "Date.h" Date::Date(int year, int month, int day)

    9810

    C++】C++ 的 IO 流

    C++流是指信息从外部输入设备(键盘)向计算机内部(内存)输入和从内存向外部输出设备(显示器)输出的过程。这种输入输出的过程被形象的比喻为 “流”。...这种转换是由编译器自动进行的,不需要从代码显式地进行调用。...答案是 istream 类内部重载了 bool: 综上,由于 istream重载了流提取运算符,所以当我们使用 while (cin >> str)去流中提取对象数据时,调用的是 operator...>>,该函数返回一个 istream类型的对象;同时,因为 istream还重载了 bool,所以 istream 对象会去调用 operator bool函数;operator bool 调用时如果接收流失败...这三个类的关系如图: 下面我们以 fstream 类为例来解释 C++ 面向对象的文件操作,其他两个类的使用和 fstream 类的使用基本一样。

    35030

    C++】IO流

    C++ 流是指信息从外部输入设备(键盘)向计算机内部(内存)输入和从内存向外部输出设备(显示器)输出的过程。这种输入输出的过程被形象的比喻为“流”。它的特性是:有序连续、具有方向性。...使用 cin 进行标准输入即数据通过键盘输入到程序,同时 C++ 标准库还提供了 cerr 用来进行标准错误的输出,以及 clog 进行日志的输出,从上图可以看出,cout、cerr、clog 是 ostream...,调用的是 operator>>,返回值是 istream 类型的对象,那么这里可以做逻辑条件值,源自于 istream 的对象又调用了operator bool(),operator bool() 调用时如果接收流失败..._date << endl; return 0; } 运行结果如下: 我们也可以在当前目录下看见新建的两个文件: 注意,以二进制方式写数据的时候,不能使用二进制方式写容器,例如我们将上述的结构的信息的...} 在 C++ ,可以使用 stringstream 类对象来避开此问题。

    15910

    使用cin进行输入

    C++为我们提供了ignore( )函数,该函数的原型如下: //第一个参数是一个数字,指定要读取忽略的最大字符数,默认为1 //第二个参数是一个字符,用作输入的分界符,默认为EOF istream &...read()方法不是专为键盘输入设计的,它最常与ostream write()函数结合使用,来完成文件输入和输出。该方法的返回类型为istream &,因此可以像getline()一样拼接使用。...putback()方法接受一个char参数——要插入的字符,其返回类型为istream &,这使得可以将该函数调用与其他istream方法拼接起来。...其使用方法如下: //read() char read_arr[100]; cin.read(read_arr, 100);//其返回值类型为istream &,可以这样拼接使用:cin.read(read_arr...]; cout << "Enter a number or a word: "; c = cin.get(); if ((c >= '0') && (c <= '9')) { cin.putback

    1.1K50

    C++cin的详细用法

    cin.get(char var)如果成功返回的是cin对象,因此可以支持链式操作,cin.get(b).get(c)。...(2)cin.get(str,size);读取一行时,只能将字符串读入C风格的字符串,即char*,但是C++的getline函数可以将字符串读入C++风格的字符串,即string类型。...条件状态的复位使用clear(),清空输入缓冲区应该使用: 函数原型:istream &ignore( streamsize num=1, int delim=EOF ); 函数作用:跳过输入流...(3)有个疑问,网上很多资料说调用cin.sync()即可清空输入缓冲区,本人测试了一下,VC++可以,但是在Linux下使用GNU C++却不行,无奈之下,linux下就选择了cin.ignore()...am lvlv[回车],输出: image.png 由于该函数是C的库函数,所以不建议使用,既然是C++程序,就尽量使用C++的库函数吧。

    7.3K30

    C++】输入输出流 ⑪ ( 文件流 | 二进制形式打开文件 | 二进制文件读取 | read 函数 | gcount 函数 | 二进制文件写出 | write 函数 | fail 函数 )

    的数据不是 字符数据 , 而是以 二进制形式 存储的 字节数据 , 有特定的格式 , : PNG 头文件 , 有特定的文件头 , 数据位 , 校验位 , 使用 文本编辑器 打开都是乱码 ; 二进制文件...); ostream& write(const char * buffer,int len); 1、二进制文件读取 - read() 函数 istreamC++ 标准库中用于处理输入流的类 , 它提供了许多方法来读取数据...; ifstream 继承 istream 类 ; read() 函数是 istream 类的一个成员函数 , 用于从输入流读取指定长度的数据并存储到指定的缓冲区 , 函数原型如下 : istream...() 函数 的 返回值是 一个 istream 对象的引用 , 可以用于链式调用 ; 2、获取实际读取的字节数 - gcount() 函数 read() 函数可以指定要读取的字节数 , 但实际读取的字节数需要调用...返回值分析 : write() 函数返回一个 ostream 对象的引用 , 可以用于链式调用 ; 2、验证输出是否出错 - fail() 函数 fail() 函数是 ostream 类的一个成员函数

    72910

    C++ 中标记字符串与getline() 函数和字符数组

    在这篇文章解释了其中的四个: 使用字符串流 一个字符串流与允许你从字符串,就好像它是一个流读取流的字符串对象关联。...它需要在循环中调用以获取所有令牌。 当没有更多标记时,它返回 NULL。...juejin Contribute 使用strtok_r() 就像 C 的 strtok() 函数一样,strtok_r() 执行相同的任务,将字符串解析为标记序列。...我们可以通过两种方式调用 strtok_r() 下面是一个简单的 C++ 程序来展示 strtok_r() 的使用: #include #include int...将字符存储在缓冲区。 提取的最大字符数为 size – 1。 注意终止符(或分隔符)可以是任何字符(' '、'、' 或任何特殊字符等)。终止符被读取但不保存到缓冲区,而是由空字符替换。

    1.4K20

    C++高阶】深入理解C++ IO流:标准库的隐藏宝石

    对于C++这一强大而灵活的编程语言而言,其丰富的I/O流库更是为开发者提供了高效、灵活且易于使用的数据交换机制 C++的I/O流库不仅涵盖了基本的输入输出操作,标准输入输出流(cin和cout)、文件流...operator>>,返回值是istream类型的对象,那么这里可以做逻辑条件值,源自于istream的对象又调用了operator bool,operator bool调用时如果接收流失败,或者有结束标志..._date << endl; return 0; } 注意:二进制读写时,尽量避免使用容器,容器存放的指针可能会在读取文件时,释放变成野指针 文件读写代码示例 (C++): // 文件流对象..._date << endl; return 0; } 4. stringstream stringstream 是 C++ 标准库的一个非常有用的类,它属于 头文件。...如果想要将一个整形变量的数据转化为字符串格式: 使用itoa()函数 (C++为 _itoa()) 使用sprintf()函数 但是两个函数在转化时,都得需要先给出保存结果的空间,那空间要给多大呢

    9810

    c++术语大总结

    字符串字面常量 cin 一个istream对象,用来从标准输入读取数据。 类 一种用于定义自己到数据结构及其相关操作的机制。类是c++中最基本的特性之一。...标准库类型种,istream estream都是类。 类类型 类定义的类型,类名即为类型名 注释 被编译器忽略的程序文本。...通常用0表示假,用非0值表示真。 cout 一个ostream 对象,用于将数据写入标准输出,通常用于程序的正常输出内容。 花括号 花括号用于划定程序块边界。左花括号为程序开始,右花括号为结束。...iostream 提供了面向流的输入输出的标准库类型 istream 提供了面向流的输入的库类型。 操纵符对象 :std::endl;在读写流的时候用来操纵流本身。...(运算符)()operator 调用运算符,跟随在函数名之后的一对括号,起到调用函数的效果。

    22030

    C++IO流详解

    C++流是指信息从外部输入设备(键盘)向计算机内部(内存)输入和从内存向外部输出设备(显示器)输出的过程。这种输入输出的过程被形象的比喻为“流”。...:标准IO流 对于 cin:在C++称为流提取,也就是在 IO流 中提取信息,比如说读文件、获取键盘的信息等 对于 cout:在C++称为流插入,也就是在 IO流 插入信息.../reference/ios/ios/operator_bool/ ​ 实际上我们看到使用 while(cin>>i) 去流中提取对象数据时,调用的是 operator>>,返回值是 istream...类型的对象,那么这里可以做逻辑条件值,源自于 istream 的对象又调用了 operator bool,operator bool 调用时如果接收流失败,或者有结束标志,则返回 false。...} 在C++,可以使用stringstream类对象来避开此问题。

    60330
    领券