我一直在开发一个在c ++下工作的流程,需要从c#中的web服务调用。
在程序的第一个版本中,c#程序成功地使用了由几个类组成的c ++ dll和一个具有静态函数的ref类。
在此之后,我创建了一个WCF Web服务并移植了我的代码:
C#webservice调用函数:
try
{
StringBuilder d = new StringBuilder(1000);
fixed (byte* pt = shelfImage)
{
vf.Operations.IdentifyBrands(pt, (int)shelfImage.Length, rowCount, columnCount, d);
}
Logger.log("Result is: " + d.ToString());
return d.ToString();
}
C ++ DLL部分:
//Importing GMM and elm data
std::string dataDir = "C:\\VisionFetchData\\";
FeatureExtractor fx;
fx.loadGMM(dataDir+"gmmCigarette.yml");
ELMClassifier* elm = new ELMClassifier(dataDir + "elmv3.bin");
//extracting features and identifying brands
std::vector<float> shelfFeatures = fx.processShelf(mImg, detected);
std::vector<int> ids = elm->classify(shelfFeatures);
程序成功运行直至最后一行,并在之前崩溃,甚至进入功能体。 ShelfFeatures的尺寸预计为50K-1M。分类器函数使用按引用调用以节省内存。
我在ELMClassifier类中使用了特征库,这就是我必须使用ELMClassifier *和new关键字的原因。我还在公共部分定义了类中使用了EIGEN_MAKE_ALIGNED_OPERATOR_NEW参数。
我试过了:
可能导致此问题的原因以及如何解决?
答案 0 :(得分:0)
这里有一个双重问题。首先,默认的.exe堆栈大小为1mb。因此,您的shelfFeatures
变量已经存储了很大一部分,位于为您的C#托管代码提供服务的堆栈顶部。您正在玩内存分配的危险游戏,因为elm->classify
会返回副本,然后将再次复制到ids
。您可以在一个时间点有效地将内存量增加一倍 - 难怪您的堆栈溢出!此外,当您创建shelfFeatures
时,您也会做同样的事情 - 它会从函数调用中复制出来。
你有几个选择。首先,在堆上分配,不要忘记随后销毁。或者,您可以设置可执行文件的堆栈大小here。
答案 1 :(得分:0)
最后解决了问题,与Eigen无关或通过引用调用。只是堆叠空间。
显然,静态分配的变量在堆栈上占用空间,而100000个元素的数组证明了它的问题。将我的内部数组(必须是静态的)更改为可管理(500)大小并解决了问题。
谢谢大家的帮助。