如何获取在外部库中定义为 char** 的 C(CDELC) 函数的输出值
How do you get the output value of a C(CDELC) function defined in an external library as char**
我希望能够使用在共享对象文件 (lib.so) 中定义的以下函数:
int encrypt_data (char* buffer_in, int size_in, char** buffer_out, int* size_out)
基本上,我希望能够将文件的内容传递给此函数 (buffer_in) 并将输出内容 (buffer_out) 写入另一个文件。这是我到目前为止尝试过的方法:
PROCEDURE encrypt_data EXTERNAL "lib.so" CDECL :
DEFINE INPUT PARAMETER buffer_in AS MEMPTR.
DEFINE INPUT PARAMETER size_in AS LONG.
DEFINE OUTPUT PARAMETER buffer_out AS MEMPTR.
DEFINE OUTPUT PARAMETER size_out AS LONG.
DEFINE RETURN PARAMETER returnvalue AS LONG.
END PROCEDURE.
PROCEDURE pi_encryptHash:
DEFINE INPUT PARAMETER ipc_fullPathToEncrypt AS CHARACTER NO-UNDO.
DEFINE VARIABLE lm_bufferIn AS MEMPTR NO-UNDO.
DEFINE VARIABLE li_sizeIn AS INT NO-UNDO.
DEFINE VARIABLE lm_bufferFakeOut AS MEMPTR NO-UNDO.
DEFINE VARIABLE lm_bufferOut AS MEMPTR NO-UNDO.
DEFINE VARIABLE li_sizeOut AS INT NO-UNDO.
DEFINE VARIABLE li_returnedCode AS INTEGER NO-UNDO.
/* make sure MEMPTR is sized correctly */
FILE-INFO:FILE-NAME = ipc_fullPathToEncrypt.
SET-SIZE(lm_bufferIn) = FILE-INFO:FILE-SIZE.
li_sizeIn = GET-SIZE(lm_bufferIn).
/* the actual read */
INPUT FROM VALUE(ipc_fullPathToEncrypt) BINARY NO-MAP NO-CONVERT.
IMPORT lm_bufferIn.
INPUT CLOSE.
/* Call the encrypt proc a first time to get the output lenght */
SET-SIZE(lm_bufferFakeOut) = 2.
RUN encrypt_data(INPUT lm_bufferIn, INPUT li_sizeIn, OUTPUT lm_bufferFakeOut, OUTPUT li_sizeOut, OUTPUT li_returnedCode).
/* Call it a second time with a buffer large enough to get the output value */
SET-SIZE(lm_bufferOut) = li_sizeOut.
RUN encrypt_data(INPUT lm_bufferIn, INPUT li_sizeIn, OUTPUT lm_bufferOut, OUTPUT li_sizeOut, OUTPUT li_returnedCode).
/* Write MEMPTR to file */
OUTPUT TO VALUE(ipc_fullPathToEncrypt + ".sha") BINARY NO-MAP NO-CONVERT.
EXPORT lm_bufferOut.
OUTPUT CLOSE.
SET-SIZE(lm_bufferIn) = 0.
SET-SIZE(lm_bufferOut) = 0.
DISPLAY li_returnedCode.
RETURN "".
END PROCEDURE.
我想我的问题是我无法读取 char** buffer_out
的数据,据我所知,它是一个指向指针的指针,所以我在这里 EXPORT lm_bufferOut.
真正导出的是我要导出的数据的指针地址?但是我怎样才能导出数据呢?
可能不是您原来问题的答案,但请注意,正在进行加密的内置函数。例如,您可以这样做(在此示例中,加密值是 base64 编码的,因此结果是 "viewable"):
DEFINE VARIABLE cClearText AS CHARACTER NO-UNDO.
DEFINE VARIABLE rBinaryKey AS RAW NO-UNDO.
DEFINE VARIABLE rEncryptedValue AS RAW NO-UNDO.
DEFINE VARIABLE cEncryptedText AS CHARACTER NO-UNDO.
DEFINE VARIABLE cDecryptedText AS CHARACTER NO-UNDO.
ASSIGN
cClearText = "This is the clear text string to be encrypted.".
MESSAGE "Original message: " cCleartext
VIEW-AS ALERT-BOX INFO BUTTONS OK.
ASSIGN
SECURITY-POLICY:SYMMETRIC-ENCRYPTION-ALGORITHM = "AES_OFB_256"
rBinaryKey = GENERATE-RANDOM-KEY
SECURITY-POLICY:SYMMETRIC-ENCRYPTION-KEY = rBinaryKey
SECURITY-POLICY:SYMMETRIC-ENCRYPTION-IV = ?
rEncryptedValue = Encrypt (cClearText)
cEncryptedText = BASE64-ENCODE(rEncryptedValue)
.
MESSAGE "Encrypted Message:" cEncryptedText
VIEW-AS ALERT-BOX INFO BUTTONS OK.
ASSIGN
SECURITY-POLICY:SYMMETRIC-ENCRYPTION-KEY = rBinaryKey
cDecryptedText = GET-STRING(DECRYPT (rEncryptedValue),1).
MESSAGE "Decrypted Message: " cDecryptedText
VIEW-AS ALERT-BOX INFO BUTTONS OK.
此示例基于 this knowledge base entry。
你可以这样做:
MESSAGE SECURITY-POLICY:SYMMETRIC-SUPPORT VIEW-AS ALERT-BOX.
查看支持的对称加密算法。
这是一个关于不同版本的 AES 算法的 SO 问题:
How to choose an AES encryption mode (CBC ECB CTR OCB CFB)?
已找到解决方法,下面是使用的程序:
PROCEDURE pi_encryptDecrypt:
DEFINE INPUT PARAMETER ipc_inputFile AS CHARACTER NO-UNDO.
DEFINE INPUT PARAMETER ipc_outputFile AS CHARACTER NO-UNDO.
DEFINE INPUT PARAMETER ipi_codeOp AS INTEGER NO-UNDO.
DEFINE VARIABLE lm_bufferIn AS MEMPTR NO-UNDO.
DEFINE VARIABLE li_sizeIn AS INT NO-UNDO.
DEFINE VARIABLE lm_bufferFakeOut AS MEMPTR NO-UNDO.
DEFINE VARIABLE lm_bufferOut AS MEMPTR NO-UNDO.
DEFINE VARIABLE li_sizeOut AS INT NO-UNDO.
DEFINE VARIABLE li_returnedCode AS INTEGER NO-UNDO.
define variable mtarget as memptr.
/* make sure MEMPTR is sized correctly */
FILE-INFO:FILE-NAME = ipc_inputFile.
SET-SIZE(lm_bufferIn) = FILE-INFO:FILE-SIZE.
li_sizeIn = GET-SIZE(lm_bufferIn).
/* the actual read */
copy-lob from file ipc_inputFile to lm_bufferIn.
/* set a buffer large enough to get the output value */
SET-SIZE(lm_bufferOut) = 8.
if ipi_codeOp = 1 then
RUN encrypt_data(INPUT lm_bufferIn, INPUT li_sizeIn, OUTPUT lm_bufferOut, OUTPUT li_sizeOut, OUTPUT li_returnedCode).
else
RUN decrypt_data(INPUT lm_bufferIn, INPUT li_sizeIn, OUTPUT lm_bufferOut, OUTPUT li_sizeOut, OUTPUT li_returnedCode).
set-size(mtarget) = li_sizeOut.
SET-POINTER-VALUE(mtarget) = GET-INT64(lm_bufferOut, 1).
/* Write MEMPTR to file */
os-delete value(ipc_outputFile).
COPY-LOB FROM mtarget for /* FOR est SUPER IMPORTANT !! - ne pas enlever */ li_sizeOut TO FILE (ipc_outputFile).
SET-SIZE(lm_bufferIn) = 0.
SET-SIZE(lm_bufferOut) = 0.
set-size(mtarget) = 0.
/*DISPLAY li_returnedCode.
DISPLAY li_sizeOut.*/
RETURN "".
END PROCEDURE.
正如我在问题中所述,问题确实是 char** buffer_out
returns 指向内存中数据的指针。
诀窍是使用第二个 MEMPTR (mtarget),它将指向实际数据,使用 SET-SIZE 将其大小设置得足够大,然后将其设置为特定内存位置的值(使用SET-POINTER-VALUE),我们从 GET-INT64(lm_bufferOut, 1).
得到
我希望能够使用在共享对象文件 (lib.so) 中定义的以下函数:
int encrypt_data (char* buffer_in, int size_in, char** buffer_out, int* size_out)
基本上,我希望能够将文件的内容传递给此函数 (buffer_in) 并将输出内容 (buffer_out) 写入另一个文件。这是我到目前为止尝试过的方法:
PROCEDURE encrypt_data EXTERNAL "lib.so" CDECL :
DEFINE INPUT PARAMETER buffer_in AS MEMPTR.
DEFINE INPUT PARAMETER size_in AS LONG.
DEFINE OUTPUT PARAMETER buffer_out AS MEMPTR.
DEFINE OUTPUT PARAMETER size_out AS LONG.
DEFINE RETURN PARAMETER returnvalue AS LONG.
END PROCEDURE.
PROCEDURE pi_encryptHash:
DEFINE INPUT PARAMETER ipc_fullPathToEncrypt AS CHARACTER NO-UNDO.
DEFINE VARIABLE lm_bufferIn AS MEMPTR NO-UNDO.
DEFINE VARIABLE li_sizeIn AS INT NO-UNDO.
DEFINE VARIABLE lm_bufferFakeOut AS MEMPTR NO-UNDO.
DEFINE VARIABLE lm_bufferOut AS MEMPTR NO-UNDO.
DEFINE VARIABLE li_sizeOut AS INT NO-UNDO.
DEFINE VARIABLE li_returnedCode AS INTEGER NO-UNDO.
/* make sure MEMPTR is sized correctly */
FILE-INFO:FILE-NAME = ipc_fullPathToEncrypt.
SET-SIZE(lm_bufferIn) = FILE-INFO:FILE-SIZE.
li_sizeIn = GET-SIZE(lm_bufferIn).
/* the actual read */
INPUT FROM VALUE(ipc_fullPathToEncrypt) BINARY NO-MAP NO-CONVERT.
IMPORT lm_bufferIn.
INPUT CLOSE.
/* Call the encrypt proc a first time to get the output lenght */
SET-SIZE(lm_bufferFakeOut) = 2.
RUN encrypt_data(INPUT lm_bufferIn, INPUT li_sizeIn, OUTPUT lm_bufferFakeOut, OUTPUT li_sizeOut, OUTPUT li_returnedCode).
/* Call it a second time with a buffer large enough to get the output value */
SET-SIZE(lm_bufferOut) = li_sizeOut.
RUN encrypt_data(INPUT lm_bufferIn, INPUT li_sizeIn, OUTPUT lm_bufferOut, OUTPUT li_sizeOut, OUTPUT li_returnedCode).
/* Write MEMPTR to file */
OUTPUT TO VALUE(ipc_fullPathToEncrypt + ".sha") BINARY NO-MAP NO-CONVERT.
EXPORT lm_bufferOut.
OUTPUT CLOSE.
SET-SIZE(lm_bufferIn) = 0.
SET-SIZE(lm_bufferOut) = 0.
DISPLAY li_returnedCode.
RETURN "".
END PROCEDURE.
我想我的问题是我无法读取 char** buffer_out
的数据,据我所知,它是一个指向指针的指针,所以我在这里 EXPORT lm_bufferOut.
真正导出的是我要导出的数据的指针地址?但是我怎样才能导出数据呢?
可能不是您原来问题的答案,但请注意,正在进行加密的内置函数。例如,您可以这样做(在此示例中,加密值是 base64 编码的,因此结果是 "viewable"):
DEFINE VARIABLE cClearText AS CHARACTER NO-UNDO.
DEFINE VARIABLE rBinaryKey AS RAW NO-UNDO.
DEFINE VARIABLE rEncryptedValue AS RAW NO-UNDO.
DEFINE VARIABLE cEncryptedText AS CHARACTER NO-UNDO.
DEFINE VARIABLE cDecryptedText AS CHARACTER NO-UNDO.
ASSIGN
cClearText = "This is the clear text string to be encrypted.".
MESSAGE "Original message: " cCleartext
VIEW-AS ALERT-BOX INFO BUTTONS OK.
ASSIGN
SECURITY-POLICY:SYMMETRIC-ENCRYPTION-ALGORITHM = "AES_OFB_256"
rBinaryKey = GENERATE-RANDOM-KEY
SECURITY-POLICY:SYMMETRIC-ENCRYPTION-KEY = rBinaryKey
SECURITY-POLICY:SYMMETRIC-ENCRYPTION-IV = ?
rEncryptedValue = Encrypt (cClearText)
cEncryptedText = BASE64-ENCODE(rEncryptedValue)
.
MESSAGE "Encrypted Message:" cEncryptedText
VIEW-AS ALERT-BOX INFO BUTTONS OK.
ASSIGN
SECURITY-POLICY:SYMMETRIC-ENCRYPTION-KEY = rBinaryKey
cDecryptedText = GET-STRING(DECRYPT (rEncryptedValue),1).
MESSAGE "Decrypted Message: " cDecryptedText
VIEW-AS ALERT-BOX INFO BUTTONS OK.
此示例基于 this knowledge base entry。
你可以这样做:
MESSAGE SECURITY-POLICY:SYMMETRIC-SUPPORT VIEW-AS ALERT-BOX.
查看支持的对称加密算法。
这是一个关于不同版本的 AES 算法的 SO 问题:
How to choose an AES encryption mode (CBC ECB CTR OCB CFB)?
已找到解决方法,下面是使用的程序:
PROCEDURE pi_encryptDecrypt:
DEFINE INPUT PARAMETER ipc_inputFile AS CHARACTER NO-UNDO.
DEFINE INPUT PARAMETER ipc_outputFile AS CHARACTER NO-UNDO.
DEFINE INPUT PARAMETER ipi_codeOp AS INTEGER NO-UNDO.
DEFINE VARIABLE lm_bufferIn AS MEMPTR NO-UNDO.
DEFINE VARIABLE li_sizeIn AS INT NO-UNDO.
DEFINE VARIABLE lm_bufferFakeOut AS MEMPTR NO-UNDO.
DEFINE VARIABLE lm_bufferOut AS MEMPTR NO-UNDO.
DEFINE VARIABLE li_sizeOut AS INT NO-UNDO.
DEFINE VARIABLE li_returnedCode AS INTEGER NO-UNDO.
define variable mtarget as memptr.
/* make sure MEMPTR is sized correctly */
FILE-INFO:FILE-NAME = ipc_inputFile.
SET-SIZE(lm_bufferIn) = FILE-INFO:FILE-SIZE.
li_sizeIn = GET-SIZE(lm_bufferIn).
/* the actual read */
copy-lob from file ipc_inputFile to lm_bufferIn.
/* set a buffer large enough to get the output value */
SET-SIZE(lm_bufferOut) = 8.
if ipi_codeOp = 1 then
RUN encrypt_data(INPUT lm_bufferIn, INPUT li_sizeIn, OUTPUT lm_bufferOut, OUTPUT li_sizeOut, OUTPUT li_returnedCode).
else
RUN decrypt_data(INPUT lm_bufferIn, INPUT li_sizeIn, OUTPUT lm_bufferOut, OUTPUT li_sizeOut, OUTPUT li_returnedCode).
set-size(mtarget) = li_sizeOut.
SET-POINTER-VALUE(mtarget) = GET-INT64(lm_bufferOut, 1).
/* Write MEMPTR to file */
os-delete value(ipc_outputFile).
COPY-LOB FROM mtarget for /* FOR est SUPER IMPORTANT !! - ne pas enlever */ li_sizeOut TO FILE (ipc_outputFile).
SET-SIZE(lm_bufferIn) = 0.
SET-SIZE(lm_bufferOut) = 0.
set-size(mtarget) = 0.
/*DISPLAY li_returnedCode.
DISPLAY li_sizeOut.*/
RETURN "".
END PROCEDURE.
正如我在问题中所述,问题确实是 char** buffer_out
returns 指向内存中数据的指针。
诀窍是使用第二个 MEMPTR (mtarget),它将指向实际数据,使用 SET-SIZE 将其大小设置得足够大,然后将其设置为特定内存位置的值(使用SET-POINTER-VALUE),我们从 GET-INT64(lm_bufferOut, 1).
得到