外部程序内存分配

时间:2017-04-15 18:51:22

标签: oracle plsql external procedure

我有一些用C编写的现有函数,它们指向两个数组,并对数据进行一些计算。我想从PL / SQL中将这些函数称为外部过程。我们的数据作为BLOB存储在Oracle中。所以,我创建了一个从PL / SQL调用的包装器共享对象。将BLOB传递给每个包装函数并在每个外部过程调用时将其解析为这两个数组感觉有点过分。所以,我做了一个名为ParseBlobToArrays的函数 看起来像:

int OracleBlobToDataArrays(OCIExtProcContext* ctx,OCILobLocator* blob,
                          //some other stuff I can't post used to parse blob, 
                          unsigned int* address1, unsigned int* address2) 
  {                
      //this isn't all the code, error checking etc here as well
      unsigned char* buf = OCIExtProcAllocCallMemory(ctx,lobLen ))

      //read blob into allocated buf 
      double* arr1 = ParseToArray1(buf,//some additional params);
      float** arr2 = ParseToArray2(buf,//some additional params); 
      *address1= (unsigned int)((uintptr_t) arr1);
      *address2= (unsigned int)((uintptr_t) arr2);
  }

然后我返回地址并将它们提供给需要它们的每个后续函数并正确设置它们:

double OtherFunctionWrapper(unsigned int address1,unsigned int address2)
{
  double* arr1 = (double*)address1;
  float** arr2 = (float**)address2;

  return DoCalculation(arr1,arr2);;
}

然后我调用我编写的Free包装器函数,该函数获取地址,再次转换为适当的类型,然后释放所有指针。

有一种我不喜欢的代码味道: 当PL / SQL似乎不支持uintptr_t / 64位二进制整数(甚至根本不暴露这些原始地址)时,C代码传递这样的内存地址。如果地址不适合UINT32,那么将地址作为UINT32进行转换并将其移动到64位操作系统将来可能会爆炸。

我可以将数据解析为数组并将它们作为OCIColls返回到PL / SQL,但后来我需要使用OCI特定的数据类型等。这更安全(我认为?),但我已经解析了BLOB并且要使用的内存。将PL / SQL支持的类型传递回PL / SQL似乎很愚蠢,只是为了传递给其他函数,当我真正需要的是指向已经存在于我想要的内存格式的数据的指针时。

有关处理此事的建议有何不同?如果正确的选项是使用支持的PL / SQL数据类型执行所有操作并相应地返回它们,我会。但我正在寻找其他选项,以便每次调用各种计算函数时最小化重复代码,因为这些外部过程的速度非常重要。

谢谢!

0 个答案:

没有答案