我可以从Progress OpenEdge ABL调用C++代码吗?
Can I call C++ code from Progress OpenEdge ABL?
是否可以从Progress ABL中执行C++代码?
具体来说,我希望使用函数SHGetKnownFolderPath(此处的文档)来确定Windows 7计算机上"文档"文件夹的位置,该计算机将文档文件夹重定向到另一个位置。
或者,是否有另一种方法可以在不检查注册表项的情况下确定此信息?
可以调用外部共享库和 DLL。
http://documentation.progress.com/output/OpenEdge113/pdfs/dvpin/dvpin.pdf
第 3 节"外部接口"是您要查找的内容。
此 http://dbappraise.com/ppt/shlib.pptx 也可能有所帮助。
C++由于命名事物的方式,经常有问题。 你最好使用普通的旧C来构建一个"填充程序",以便在OpenEdge和C++之间架起桥梁
。不过,调用Windows系统函数通常很容易。 像这样:
procedure SHGetKnownFolderPath external "pathToLibrary":
define parameter a as someType.
define parameter b as someType.
define return parameter x as someType.
end.
查看"编程接口"文档"外部程序接口"部分。
此外,某些版本的 ABL 还支持直接 .NET 调用作为选项。
在咨询了一些来源后,我能够在 10.2B 中使用它:
- C# 解决方案,例如:https://stackoverflow.com/a/21953690/763102
- Win32 OpenEdge 示例,用于翻译示例:http://www.oehive.org/book/export/html/385.html
SHGetKnownFolderPath的困难部分是需要通过引用传递的rfid
参数。C# 具有批注[System.Runtime.InteropServices.MarshalAs(UnmanagedType.LPStruct)]
或 ref
关键字。由于 Progress OpenEdge 对外部过程参数数据类型的限制,我无法弄清楚如何传递 System.Guid
的引用,所以我执行了 .NET Guid
的字节副本并通过 MEMPTR
传递了它。对于在这里如此依赖 .NET,我深表歉意。
下面是一个工作示例,它获取提供的已知文件夹 GUID,以及获取文档文件夹的用法:
PROCEDURE SHGetKnownFolderPath EXTERNAL "shell32.dll":
DEFINE INPUT PARAMETER rfid AS MEMPTR.
DEFINE INPUT PARAMETER dwFlags AS UNSIGNED-LONG.
DEFINE INPUT PARAMETER hToken AS LONG.
DEFINE OUTPUT PARAMETER ppszPath AS LONG.
DEFINE RETURN PARAMETER result AS LONG.
END PROCEDURE.
FUNCTION prepareGuidPointer RETURNS MEMPTR(
pGuid AS System.Guid):
DEFINE VARIABLE lGuidBytes AS INTEGER EXTENT.
ASSIGN lGuidBytes = pGuid:ToByteArray().
DEFINE VARIABLE lGuidPointer AS MEMPTR NO-UNDO.
SET-SIZE(lGuidPointer) = EXTENT(lGuidBytes).
DEFINE VARIABLE ii AS INTEGER NO-UNDO.
DO ii = 1 TO EXTENT(lGuidBytes):
PUT-BYTE(lGuidPointer, ii) = lGuidBytes[ii].
END.
RETURN lGuidPointer.
END FUNCTION.
FUNCTION deallocatePointer RETURNS INT64(
pPointer AS MEMPTR):
SET-SIZE(pPointer) = 0.
RETURN GET-SIZE(pPointer).
END FUNCTION.
FUNCTION GetKnownFolderPath RETURNS CHARACTER(
pGuidString AS CHARACTER):
DEFINE VARIABLE lDontVerifyFolderFlag AS INT64 NO-UNDO
INITIAL 16384. /* 0x4000 */
DEFINE VARIABLE lUseDefaultUser AS INTEGER NO-UNDO
INITIAL 0.
DEFINE VARIABLE lGuidPointer AS MEMPTR NO-UNDO.
ASSIGN lGuidPointer = prepareGuidPointer( NEW System.Guid(pGuidString) ).
DEFINE VARIABLE lResult AS INTEGER NO-UNDO.
DEFINE VARIABLE lPathResponse AS INTEGER NO-UNDO.
RUN SHGetKnownFolderPath(
INPUT lGuidPointer,
INPUT lDontVerifyFolderFlag,
INPUT lUseDefaultUser,
OUTPUT lPathResponse,
OUTPUT lResult).
deallocatePointer(lGuidPointer).
IF lResult GE 0 THEN
DO:
DEFINE VARIABLE lStringPath AS CHARACTER NO-UNDO.
DEFINE VARIABLE lPathPointer AS System.IntPtr NO-UNDO.
ASSIGN lPathPointer = NEW System.IntPtr(lPathResponse).
ASSIGN lStringPath =
System.Runtime.InteropServices.Marshal:PtrToStringUni(lPathPointer).
System.Runtime.InteropServices.Marshal:FreeCoTaskMem(lPathPointer).
RETURN lStringPath.
END.
ELSE
UNDO, THROW NEW System.Runtime.InteropServices.ExternalException(
"Unable to retrieve the known folder path. It may not be available on this system.",
lResult).
END FUNCTION.
DEFINE VARIABLE lDocumentsGuidString AS CHARACTER NO-UNDO
INITIAL "~{FDD39AD0-238F-46AF-ADB4-6C85480369C7}".
MESSAGE GetKnownFolderPath(lDocumentsGuidString)
VIEW-AS ALERT-BOX.
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 代码在main()中运行,但在函数中出现错误
- 在VS代码中交叉编译Windows与Linux上的MinGW的SDL程序
- 编译包含字符串的代码时遇到问题
- 我在c++代码中生成了一个运行时#3异常
- 如何在linux终端中同时编译和运行c++代码
- 为cl.exe(Visual Studio代码)指定命令行C++版本
- 在Linux for Windows上编译C++代码时出错
- 我的字符计数代码计算错误.为什么
- 孤立代码块在结构中引发异常
- 在编译C++代码(具有dlib和opencv)到WASM时面临问题
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 此代码是否违反一个定义规则
- 为什么我的代码在输出中增加了93天
- 我的简单if-else语句是如何无法访问的代码
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- 为什么在这个代码结束循环中没有得到结束
- 在c代码之间共享数据的最佳方式
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值