Skip to content

Windows 64 bits issue with C API #15990

@jlaheurte

Description

@jlaheurte
System information (version)
  • OpenCV => 3.4.4 and later
  • Operating System / Platform => Windows 64 bits
  • Compiler => Visual Studio 2017
Detailed description

Starting with rev. 8a3c394 C structure constructors are disabled when building OpenCV but enabled when building a program that uses OpenCV. Relevant part of the diff is:

--- a/modules/core/include/opencv2/core/types_c.h
+++ b/modules/core/include/opencv2/core/types_c.h
@@ -44,9 +44,7 @@
 #ifndef OPENCV_CORE_TYPES_H
 #define OPENCV_CORE_TYPES_H
 
-#if !defined(__OPENCV_BUILD) && !defined(CV__DISABLE_C_API_CTORS)
 #define CV__ENABLE_C_API_CTORS // enable C API ctors (must be removed)
-#endif

This leads to an interesting problem when using, for instance, cvGetSize. According to https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=vs-2017 when a function returns a struct with a size less than 64 bits:

  • If it's a POD, it is returned in RAX
  • If not, the caller creates a temporary and passes a reference to it in RCX; function arguments are shifted

So here, when building OpenCV, CvSize is a POD, so the function assumes RCX contains the pointer to the CvArr argument. But when using the function, CvSize is not a POD any more, and the caller puts a reference to a temporary CvSize in RCX and the argument in RDX... As you can imagine, this doesn't work very well.

The workaround is obviously to define CV__DISABLE_C_API_CTORS when building my own code, but such a runtime failure with no warning is a bit disheartening.

Steps to reproduce

Use cvGetSize on an IplImage in a 64 bits Windows program. This leads to a "Bad argument (Array should be CvMat or IplImage)", unless by change your temporary CvSize has the right magic value packed in...

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions