PX Transform Routine 编译问题
PX Transform Routine compile issues
我有一个用 C++ 编写的转换器例程,它设置为清除所有空格并在输入字符串为 null 或空时映射到一个值。 C++ 代码编译并已正确测试,但我无法让例程在 Datastage 中工作。
按照说明,我已经复制了我在 DS 环境中的确切编译器选项,如下所示。
g++ -c -O -fPIC -Wno-deprecated -m64 -mtune=generic -mcmodel=small BlankToValue.cpp
g++ -shared -m64 BlankToValue.so BlankToValue.o
在作业中测试例程时出现以下错误。
Sequential_File_36,0: 内部错误: (shbuf): iomgr/iomgr.C: 2649
我应该使用一组不同的选项进行编译吗?
供参考,c++ 代码。
#include <stdlib.h>
#include <stdio.h>
#include <algorithm>
#include <locale.h>
#include <locale>
char * BlankToValue(char *InStr, char *RepStr)
{
if (InStr[0] == '[=11=]') // Check for null pointer at first character of input string.
{
return RepStr; // Return replacement string if true. This is to prevent unnecessary processing.
} else
{
const char* checkstr = InStr; // Establish copy of inputstring stored in checkstring.
do { // Start outer loop.
while (isspace(*checkstr)) { // Inner loop while current checkstring byte is whitespace.
++checkstr; // Increment to next checkstring byte.
}
} while ((*InStr++ = *checkstr++)); // Set inputstring byte to current checkstring and iterate both. Breaks when either string evaluates to null.
*InStr = '[=11=]'; // Set null terminator for input string at current byte location.
if (InStr[0] == '[=11=]') // Checks first character of cleaned input string for null pointer.
{
return RepStr; // Return replacement string if true.
} else
{
return InStr; // Return new input string if false.
}
}
}
威廉,
在指向此自定义函数的 DataStage 例程定义中,您是否 select 例程类型为对象(.o 在作业 运行 中编译到转换器阶段的文件时间)或库(在作业 运行 时加载的 lib.so 文件,但对库命名约定有要求并且该库位于库路径中)。您上面的代码表明您正在创建一个 *.so 文件但没有以 lib 为前缀。这是一个例子:
https://www.ibm.com/support/pages/node/403041
此外,如果作业日志中的第一个错误不是库加载错误而是内部错误 (shbuf) 错误,我发现过去在自定义例程中发生过这种情况:
自定义例程与您的一样涉及空值处理,并且在升级到 Information Server 8.5 后当我们的产品中的空值处理规则发生变化时开始失败。此处解释了更改:
https://www.ibm.com/support/pages/node/433863
您可以通过 运行 使用新的作业级别环境变量来测试这是否是问题:APT_TRANSFORM_COMPILE_OLD_NULL_HANDLING=1
在另一种情况下,自定义例程中的 shbuf 错误是转换阶段接收到大记录的结果(大于自定义例程中定义的数据类型可以处理的记录)。在所有字符串类型字段中仅使用具有小值的单个示例输入记录时,作业是否仍然失败。
谢谢。
此外,我注意到错误来自顺序文件阶段,而不是使用自定义例程的转换器阶段。因此,可能还需要考虑您的自定义例程的输出数据类型是什么,并确保它以有效值退出,该值对于数据类型而言不会太大,并且不会大于阶段之间使用的默认传输缓冲区大小(默认为 128k)。
经过一两天的多次尝试尝试不同的编译和编码方法后,我找到了问题的解决方案。以下代码在传递空列时抛出分段错误。回想起来这是有道理的。
if (InStr[0] == '[=10=]')
已更正为以下内容,现在一切正常。
if ((InStr == NULL) || (InStr[0] == '[=11=]'))
我有一个用 C++ 编写的转换器例程,它设置为清除所有空格并在输入字符串为 null 或空时映射到一个值。 C++ 代码编译并已正确测试,但我无法让例程在 Datastage 中工作。
按照说明,我已经复制了我在 DS 环境中的确切编译器选项,如下所示。
g++ -c -O -fPIC -Wno-deprecated -m64 -mtune=generic -mcmodel=small BlankToValue.cpp
g++ -shared -m64 BlankToValue.so BlankToValue.o
在作业中测试例程时出现以下错误。
Sequential_File_36,0: 内部错误: (shbuf): iomgr/iomgr.C: 2649
我应该使用一组不同的选项进行编译吗?
供参考,c++ 代码。
#include <stdlib.h>
#include <stdio.h>
#include <algorithm>
#include <locale.h>
#include <locale>
char * BlankToValue(char *InStr, char *RepStr)
{
if (InStr[0] == '[=11=]') // Check for null pointer at first character of input string.
{
return RepStr; // Return replacement string if true. This is to prevent unnecessary processing.
} else
{
const char* checkstr = InStr; // Establish copy of inputstring stored in checkstring.
do { // Start outer loop.
while (isspace(*checkstr)) { // Inner loop while current checkstring byte is whitespace.
++checkstr; // Increment to next checkstring byte.
}
} while ((*InStr++ = *checkstr++)); // Set inputstring byte to current checkstring and iterate both. Breaks when either string evaluates to null.
*InStr = '[=11=]'; // Set null terminator for input string at current byte location.
if (InStr[0] == '[=11=]') // Checks first character of cleaned input string for null pointer.
{
return RepStr; // Return replacement string if true.
} else
{
return InStr; // Return new input string if false.
}
}
}
威廉,
在指向此自定义函数的 DataStage 例程定义中,您是否 select 例程类型为对象(.o 在作业 运行 中编译到转换器阶段的文件时间)或库(在作业 运行 时加载的 lib.so 文件,但对库命名约定有要求并且该库位于库路径中)。您上面的代码表明您正在创建一个 *.so 文件但没有以 lib 为前缀。这是一个例子: https://www.ibm.com/support/pages/node/403041
此外,如果作业日志中的第一个错误不是库加载错误而是内部错误 (shbuf) 错误,我发现过去在自定义例程中发生过这种情况:
自定义例程与您的一样涉及空值处理,并且在升级到 Information Server 8.5 后当我们的产品中的空值处理规则发生变化时开始失败。此处解释了更改: https://www.ibm.com/support/pages/node/433863 您可以通过 运行 使用新的作业级别环境变量来测试这是否是问题:APT_TRANSFORM_COMPILE_OLD_NULL_HANDLING=1
在另一种情况下,自定义例程中的 shbuf 错误是转换阶段接收到大记录的结果(大于自定义例程中定义的数据类型可以处理的记录)。在所有字符串类型字段中仅使用具有小值的单个示例输入记录时,作业是否仍然失败。
谢谢。
此外,我注意到错误来自顺序文件阶段,而不是使用自定义例程的转换器阶段。因此,可能还需要考虑您的自定义例程的输出数据类型是什么,并确保它以有效值退出,该值对于数据类型而言不会太大,并且不会大于阶段之间使用的默认传输缓冲区大小(默认为 128k)。
经过一两天的多次尝试尝试不同的编译和编码方法后,我找到了问题的解决方案。以下代码在传递空列时抛出分段错误。回想起来这是有道理的。
if (InStr[0] == '[=10=]')
已更正为以下内容,现在一切正常。
if ((InStr == NULL) || (InStr[0] == '[=11=]'))