Впоследствии у меня есть DLL C#, также в Visual Studio 2022, которая действует как оболочка. Он использует P/Invoke для включения всех функций из DLL C++, а затем предоставляет их как методы класса.
Когда я вызываю метод, предоставляемый моей DLL C#, для запуска потока из проекта используя C# DLL, поток работает с определенной скоростью (я отслеживаю скорость в Диспетчере задач -> Производительность -> Сеть, Кбит/с, поскольку потоки захватывают изображения с камеры и передают поток через HTTP).
Проблема в том, что эта скорость ниже по сравнению с тем, когда я изменяю проект C++ DLL с .dll на .exe, создаю тестовый основной файл и запускаю поток. (В данном случае она имеет более высокую скорость.)
Мне нужна моя DLL, чтобы обеспечить максимальную скорость, достигаемую при запуске из основной системы C++.
Если код потока под DLL в обоих случаях один и тот же, но в одном случае он выполняется в файле .dll, а в другом случае непосредственно в одном и том же исполняемом файле, может ли это повлиять? Как этого добиться?
Пример основного кода с правильной производительностью:
Код: Выделить всё
int main()
{
CCamFlir cam1 = CCamFlir(TCModel::A70, "10.0.0.102");
cam1.OnConnect();
cam1.OnSetLivePort(7001);
cam1.SetTransmission(1);
cam1.SetEmissivity(1);
cam1.SetAutoRange(false);
cam1.OnLoadPalette(TCPalette::IRON, 18, 40);
cam1.OnSetZoom(1.0, 0, 0);
cam1.setCamBeforeStream();
cam1.StartThermalStream();
cam1.OnSetLiveThreadFrequency(30);
cam1.OnSetAcquisitionTCFrameRate(FrameRateAvailable::HZ30);
cam1.OnDrawRoiSquare(6, "", 50, 50, 255, 0, 0, 255, 255, 255, FontType::FONT_HERSHEY_PLAIN,
2, 50, 50, 55, 55);
cam1.StartHTTPServer(60000);
int conta = 0;
while (true)
{
//if (cv::waitKey(33) == 27) // Exit when ESC is pressed
// break;
//std::this_thread::sleep_for(std::chrono::milliseconds(1000));
//conta++;
//if (conta == 10) {
// cam1.OnSetRange(LOW);
//}
}
return 0;
}
Код: Выделить всё
void UpdateCurrentFrame(CCamFlir* camInstance)
{
try
{
camInstance->isTerminateUpdateCurrentFrameThread = false;
high_resolution_clock::time_point start;
high_resolution_clock::time_point end;
int frames = 0;
high_resolution_clock::time_point fps_timer = high_resolution_clock::now();
camInstance->m_rawImageLive = Image::Create();
std::atomic shouldTerminate(false);
while (!camInstance->m_terminate)
{
start = high_resolution_clock::now();
high_resolution_clock::time_point iteration_start = high_resolution_clock::now();
try
{
camInstance->m_rawImageReceive = camInstance->m_cam->GetNextImage();
if (!camInstance->m_rawImageReceive->IsIncomplete() || camInstance->m_rawImageReceive->GetImageStatus() == 0)
{
camInstance->m_rawImageLive->DeepCopy(camInstance->m_rawImageReceive);
}
}
catch (std::exception& ex)
{
std::string e = ex.what();
camInstance->m_status = DISCONNECTED;
}
end = high_resolution_clock::now();
long duration = duration_cast(end - start).count();
std::chrono::milliseconds durataMilliseconds(duration);
camInstance->m_iterationTime = durataMilliseconds;
frames++;
camInstance->m_rawImageReceive->Release();
auto elapsed = duration_cast(end - fps_timer).count();
if (elapsed >= 1) {
camInstance->m_effectiveFrameRate = static_cast(frames) / elapsed;
fps_timer = high_resolution_clock::now();
frames = 0;
}
}
camInstance->isTerminateUpdateCurrentFrameThread = true;
}
catch (const std::exception& ex)
{
std::string eccezione = ex.what();
camInstance->m_status = DISCONNECTED;
camInstance->isTerminateUpdateCurrentFrameThread = true;
}
}
Код: Выделить всё
bool CCamFlir::StartThermalStream()
{
try
{
m_cam->BeginAcquisition();
if (m_getNextImageThread.joinable())
m_getNextImageThread.join();
m_getNextImageThread = std::thread(UpdateCurrentFrame, this);
if (m_getLiveImage.joinable())
m_getLiveImage.join();
m_getLiveImage = std::thread(GetLiveImage, this);
if (m_updateROIValue.joinable())
try
{
m_updateROIValue.join();
}
catch (const std::exception& ex)
{
std::cout StartThermalStream(); }
Код: Выделить всё
[DllImport("lib\\DriverFlir.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern bool CamFlir_StartThermalStream(IntPtr cam);
private IntPtr PtrCam { get; set; }
public void StartStream()
{
CamFlir_SetCamBeforeStream(PtrCam);
CamFlir_StartThermalStream(PtrCam);
}
Код: Выделить всё
namespace CameraFlir
{
public class Program
{
public static void Main(string[] args)
{
string ip = "10.0.0.102";
byte[] byteArray = Encoding.UTF8.GetBytes(ip);
CameraFlir cam1 = new CameraFlir(DriverFlir.TCModel.A70, byteArray);
cam1.Connect();
cam1.Transmission = 1;
cam1.Emissivity = 1;
cam1.SetAutoRange(true);
cam1.SetPalette(DriverFlir.TCPalette.IRON);
cam1.SetZoom(1, 0, 0);
cam1.StartStream();
cam1.LiveFps = 30;
cam1.AcqusitionTCFrequency = DriverFlir.FrameRateAvailable.HZ30;
cam1.StartHTTPServer(65000);
while (true)
{
}
}
}
}
Низкая производительность сети при вызове из C#
Я ожидаю, что на скорость влияет изменение языка вызова, но после запуска потока разве сам поток не должен быть таким же? Разве он не должен знать о вызывающем объекте и функционировать таким же образом?
Подробнее здесь: https://stackoverflow.com/questions/786 ... d-of-a-exe
Мобильная версия