gpt4 book ai didi

c# - 在 C# 中的 Parallel.For 中调用 native dll 会抛出 System.AccessViolationException

转载 作者:太空宇宙 更新时间:2023-11-03 15:28:21 24 4
gpt4 key购买 nike

我有一个 C++ dll,它使用 OpenCV 和 Libtiff 进行一些图像处理。它在给定输入文件(专有格式)的情况下创建多页 tif 文件,一次一个文件。

我有一个 C# 类,我在其中为所有需要转换的文件循环调用此 dll。当我从普通的 for 循环调用 dll 时,它工作正常。当我尝试从 Parallel.For 调用它时,它崩溃并抛出 System.AccessViolationException。

动态链接库代码:

extern "C"
{
__declspec(dllexport) int _cdecl extractFisAndCreateGeotiff(char* fisFile, char* infoFisFile, char *tifFile, bool allLayers, double latitude, double longitude, double realX, double realY, double heading);
}

int extractFisAndCreateGeotiff(char* fisFile, char* infoFisFile, char* geotifFile, bool allLayers, double latitude, double longitude, double heading, double realLength, double realWidth)
{
//GET LCMS SENSOR INFO
if(!getLCMSInfo(fisFile))
if(!getLCMSInfo(infoFisFile))
return NO_LCMS_INFO;

vector<Mat> fisData = extractFisData(allLayers, info, std::string(fisFile));
saveAsGeoTiff(std::string(geotifFile), allLayers, fisData, latitude, longitude, realLength, realWidth, heading);

return SUCCESS;
}

//FUNCTION TO EXTRACT BUFFERS FROM FIS FILE
vector<Mat> extractFisData(bool allLayers, LcmsSystemInfo info, string fisFileName)
{
int nLayers = (allLayers) ? NUM_PAGES_ALL : NUM_PAGES_STRIPPED;
vector<Mat> fisData(nLayers);
GetIntensityImage(fisFileName, &info, fisData[0]);
GetRangeImage(fisFileName, &info, fisData[1]);
if(allLayers)
{
getLeftAndRightIntensity(fisData[2], fisData[3], &info);
getLeftAndRightRange(fisData[4], fisData[5], &info);
}

for (int i=0; i<nLayers; i++)
flip(fisData[i], fisData[i], 0);
return fisData;
}

//FUNCTION TO CREATE GEOTIFF GIVEN THE BUFFERS
void saveAsGeoTiff(string geoTifName, bool allLayers, vector<Mat> fisData, double lattitude, double longitude, double imageLatDist, double imageLongDist, double heading)
{
int num_pages = (allLayers) ? NUM_PAGES_ALL : NUM_PAGES_STRIPPED;
TIFFSetErrorHandler(NULL);
TIFFSetWarningHandler(NULL);
augment_libtiff_with_custom_tags();
TIFF *tiffdata = TIFFOpen(geoTifName.c_str(), "w");
for(int page = 0; page<num_pages; page++)
{
setCoreTiffTags(tiffdata, page, num_pages, fisData[page]);
if(page==0)
{
setCustomTiffTags(tiffdata, allLayers);
setGeoTiffTags(tiffdata, lattitude, longitude, imageLatDist, imageLongDist, heading, fisData[page]);
}
TIFFWriteEncodedStrip(tiffdata, 0, static_cast<void *>(fisData[page].data), fisData[page].rows*fisData[page].step[0]);
TIFFWriteDirectory(tiffdata);
}
TIFFClose(tiffdata);
}

C# dll 调用:

[DllImport("roadware.Algorithm.GeotiffProcessor.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern int extractFisAndCreateGeotiff(String fisFile, String infoFisFile, String tifFile, bool allLayers, double latitude, double longitude, double realX, double realY, double heading);

private void CreateGeotifFiles(List<string> fisFilesList, string infoFisFile, List<string> tiffFilesList, List<double> geoPositions, List<double> fisRealSizes, List<double> headings)
{
ParallelOptions po = new ParallelOptions();
po.MaxDegreeOfParallelism = Environment.ProcessorCount * 2;
Parallel.For(0, fisFilesList.Count, po, i =>
//for (int i = 0; i < fisFilesList.Count; i++)
{
extractFisAndCreateGeotiff(fisFilesList[i], infoFisFile, tiffFilesList[i], this.settings.ExtractAll, geoPositions[i * 2], geoPositions[i * 2 + 1], fisRealSizes[i * 2], fisRealSizes[i * 2 + 1], headings[i]);
}
);
}

从普通 for 循环调用时没有错误,仅从 Parallel.For 调用。我是并行编程和线程的新手。任何帮助将不胜感激!

异常: enter image description here

调用堆栈: enter image description here

最佳答案

几点建议:1.有初始化调用,肯定是在修改全局状态,试一下2. 有时c dll 根本不是线程安全的,有时它们是本地线程安全的。在 parallel.for 的情况下,您将重新使用相同的线程,因此如果您明确尝试每个图像一个线程,您可能会更好。

此外,搜索提示:“libtiff thread safe”

关于c# - 在 C# 中的 Parallel.For 中调用 native dll 会抛出 System.AccessViolationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34474305/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com