【发布时间】:2020-07-25 18:43:44
【问题描述】:
我想不出一个更好的更具描述性的标题,因为它涉及 3 种语言,我现在将对其进行解释。
我围绕一个 Python 模块编写了一个 C++ 包装器,顺便说一下,它在 C++ 中工作得很好。我用这个包装器制作了一个 DLL,并将一些功能作为 C 公开,并在 C# 应用程序中使用它们。
问题是,如果我不显示网络摄像头源,C# 应用程序就会挂起。
也就是在Python 模块中有这个条件:
if self.debug_show_feed:
cv2.imshow('service core face Capture', frame)
当设置为True 时,将显示网络摄像头供稿。
这主要是我放置的调试内容,对于实际生产需要禁用它。在 C++ 上很好
我可以将其设置为false(通过构造函数),一切都很好。
但是,在C# 上,这种行为不会发生,如果我尝试使用模块而不将网络摄像头提要设置为true,C# 应用程序挂起,这是因为调用主操作的Start()成为阻塞调用,并且不返回任何回调。
顺便说一下我的DllImport如下:
[DllImport(@"Core_DLL.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int Initialize(bool showFeed);
[DllImport(@"Core_DLL.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void Start(bool async);
[DllImport(@"Core_DLL.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void Stop();
[DllImport(@"Core_DLL.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void SetCpuAffinity(int mask);
public delegate void CallbackDelegate(bool status, string message);
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[DllImport(@"Core_DLL.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void AddCallback(IntPtr fn);
[DllImport(@"Core_DLL.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void RemoveCallback(IntPtr fn);
这是我的 C# 回调:
private CallbackDelegate del;
public void SetUpCallback()
{
txtLog.Text += "Registering C# callback...\r\n";
del = new CallbackDelegate(callback01);
AddCallback(Marshal.GetFunctionPointerForDelegate(del));
txtLog.Text += "Calling passed C++ callback...\r\n";
}
bool status;
string id;
public void callback01(bool status, string id)
{
this.status = status;
this.id = id;
}
这是执行的主要 python 模块:
def start(self):
try:
self.is_running = True
self._main_loop()
except Exception as ex:
path='exceptions-servicecore.log'
track = traceback.format_exc()
exception_time = datetime.now().strftime("%d/%m/%Y %H:%M:%S")
with open(path, 'a') as f:
f.writelines(f'\n{exception_time} : exception occured {ex.args} \n{track}')
def start_async(self):
st = threading.Thread(target=self.start)
st.start()
def _main_loop(self):
name = None
is_valid = False
while self.is_running and self.cap.isOpened():
is_success, frame = self.cap.read()
if is_success:
name="sth"
is_valid=True
self._execute_callbacks(is_valid, name, frame)
self._execute_c_callbacks(is_valid, name)
if self.debug_show_feed:
cv2.imshow('service core face Capture', frame)
if self.save:
self.video_writer.write(frame)
if (cv2.waitKey(1)&0xFF == ord('q')) or (not self.is_running):
break
self.cap.release()
if self.save:
self.video_writer.release()
cv2.destroyAllWindows()
知道这只发生在C# 而不是C++,我可能在我的编组或我尝试在这种情况下使用C# 回调的方式中遇到一些问题。
这是一个 Visual Studio,其中包含一个演示此功能的最小示例:https://workupload.com/file/epsgzmMMVMY
这里有什么问题?为什么cv.imshow() 会导致这种行为?
【问题讨论】:
标签: c# python c++ unmanaged pybind11