将 QPDF 与 C# 结合使用
Using QPDF with C#
我正在尝试翻译这个qpdf命令:
qpdf --qdf --object-streams=禁用输入.pdf可编辑.pdf
进入我在使用 qpdf dll 时需要的等效方法调用(可从此处获得:https://sourceforge.net/projects/qpdf/(。
我通过 dumpbin 运行 qpdf dll 来获取函数名称,通过查看包含在 c++ 项目中的头文件,我可以看到函数的参数。
例如,赋予上面的 --object-streams 选项所需的函数(据我所知(是这个函数:
void setObjectStreamMode(qpdf_object_stream_e);
从 C++ 头文件变为:
[DllImport("qpdf21.dll")]
static extern void _ZN10QPDFWriter19setObjectStreamModeE20qpdf_object_stream_e(int stateEnum);
在 C# 文件中。
问题是当我使用上述功能时,我得到一个
访问冲突异常:试图读取或写入受保护的内存
错误,这让我认为我需要以某种方式创建一个 QPDF 对象,但我从未使用过面向对象的 pinvokes,所以我不知道如何在 c# 中使对象可访问。
如果有人已经熟悉在 C# 甚至 C++ 中使用 dll,并且可以告诉我要调用的正确函数来复制命令,我将不胜感激!
我已经设法弄清楚了,下面的代码复制了该命令,结果发现我正在查看错误的头文件:
[DllImport("qpdf21.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
static extern IntPtr qpdf_init();
[DllImport("qpdf21.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
static extern void qpdf_cleanup(ref IntPtr qpdfData);
[DllImport("qpdf21.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
static extern int qpdf_read(IntPtr qpdfdata, [MarshalAs(UnmanagedType.LPStr)] string fileName, IntPtr password);
[DllImport("qpdf21.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
static extern void qpdf_set_object_stream_mode(IntPtr qpdf, int mode);
[DllImport("qpdf21.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
static extern void qpdf_set_qdf_mode(IntPtr qpdf, int value);
[DllImport("qpdf21.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
static extern int qpdf_init_write(IntPtr qpdf, [MarshalAs(UnmanagedType.LPStr)] string fileName);
[DllImport("qpdf21.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
static extern int qpdf_write(IntPtr qpdf);
static void Main(string[] args)
{
//call init
IntPtr qpdfData = qpdf_init();
//call read (which gets and processes the input file)
//0 result == good
int result = qpdf_read(qpdfData, @"scan.pdf", IntPtr.Zero);
//call init_write
result = qpdf_init_write(qpdfData, @"scanEditable.pdf");
//set write options
//disable object stream mode
qpdf_set_qdf_mode(qpdfData, 1);
qpdf_set_object_stream_mode(qpdfData, 0);
//call write
result = qpdf_write(qpdfData);
//call cleanup
qpdf_cleanup(ref qpdfData);
}
看起来你在这里找到了一个很好的答案。您已经发现了 C API,它旨在帮助通过 DLL 从C++以外的语言使用 QPDF。C API 主要记录在 qpdf-c.h 头文件中。您也可以在手册的"使用其他语言"部分找到一些信息。C API 不会公开 qpdf C++库的全部功能。如果您发现缺失的部分,请随时在 github 上创建一个问题。当我添加新接口时,我尝试更新 C API,但我不会为每个接口都这样做,并且 CLI 中的某些功能直接在工具中实现,不会映射到单个库函数。
如果 C API 对于您的用例来说不够丰富,也可以使用一些声明extern "C"
函数编写自己的 C++ 类,导出它们,并构建一个额外的 DLL,您可以按照上面找到的方式使用。您可以将 qpdf-c.cc 作为其工作原理的示例。
- 多态性和功能结合
- 将 Vulkan 与 SFML 结合使用?
- 将 c++ 生成器应用程序与外部 dll 结合使用
- 如何将增强MSM与增强信号结合使用?
- MS Visual Studio 解决方案结合了非托管C++项目和 C# 项目
- 函数未在作用域中声明 / 如何结合使用 header.h、header.cpp 和 main.cpp?
- 将预编译的 C 共享库与 JNI/NDK 结合使用
- C++ 将函数指针与最佳性能相结合
- 将 Lua 与 C++ DLL 结合使用
- 为什么push_back和emplace_back结合在一起时,会有不同的行为
- 将 aws-iot-device-sdk-cpp-v2 与 CMake 结合使用
- 将2个欧拉角与GLM相结合的问题
- 结合std::execution和OpenMP是否可取
- 抽象和派生与std::list相结合
- 想要将 CGAL 与四元数相结合是否合乎逻辑
- 存储/传递 v8 承诺解析器供以后使用的最佳实践?(结合C++线程)
- 如何将 IAudioClient3 (WASAPI) 与实时工作队列 API 结合使用
- 可变参数模板与默认模板参数相结合
- 函数与返回类型 node* 与 C++ 中的 OOP 结合使用
- 将 QPDF 与 C# 结合使用