1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-31 00:03:03 +04:00

Merge pull request #28143 from Shubh3155:fix-js-ptr-factory-namespace

Fix JS bindings for namespaced Ptr factory return types #28143

This PR fixes an issue in the JS bindings generator for factory functions returning cv::Ptr<T> where T belongs to a namespaced class (for example cv::ximgproc::EdgeDrawing).
The generator previously produced unqualified C++ template arguments such as:
.constructor(select_overload<Ptr<EdgeDrawing>()>(&cv::ximgproc::createEdgeDrawing))

This results in invalid C++ because EdgeDrawing is not found in the global namespace.

Fixes https://github.com/opencv/opencv/issues/28130

In modules/js/generator/embindgen.py, inside both:

gen_function_binding_with_wrapper

gen_function_binding

a check is added:

When factory == True,

And the return type begins with Ptr<...>,

And the inner type is missing a namespace (::),
Ptr<T>  →  Ptr<class_info.cname>

This ensures the fully-qualified class name (e.g. cv::ximgproc::EdgeDrawing) is used in the generated bindings.

.constructor(select_overload<Ptr<cv::ximgproc::EdgeDrawing>()>(&cv::ximgproc::createEdgeDrawing))

Configured OpenCV with:
cmake .. -DBUILD_opencv_js=ON

Ran:
make -j gen_opencv_js_source

JS generator completed successfully without errors.

This change does not modify generated files directly — it modifies the generator logic so the correct namespace is applied automatically.
This commit is contained in:
shubham khatri
2025-12-09 14:35:55 +05:30
committed by GitHub
parent 0e2373557b
commit 498853d996
+17 -4
View File
@@ -523,13 +523,20 @@ class JSWrapperGenerator(object):
# Return type
ret_type = 'void' if variant.rettype.strip() == '' else variant.rettype
if ret_type.startswith('Ptr'): #smart pointer
# FIX: Ensure namespaced smart-pointer return types in factory methods, e.g.:
# Ptr<EdgeDrawing> → Ptr<cv::ximgproc::EdgeDrawing>
if factory and class_info is not None and ret_type.startswith('Ptr<'):
inner = ret_type[len('Ptr<'):-1].strip()
if '::' not in inner and inner == class_info.name:
ret_type = 'Ptr<%s>' % class_info.cname
if ret_type.startswith('Ptr'): # smart pointer
ptr_type = ret_type.replace('Ptr<', '').replace('>', '')
if ptr_type in type_dict:
ret_type = type_dict[ptr_type]
for key in type_dict:
if key in ret_type:
ret_type = re.sub(r"\b" + key + r"\b", type_dict[key], ret_type)
for key in type_dict:
if key in ret_type:
ret_type = re.sub(r"\b" + key + r"\b", type_dict[key], ret_type)
arg_types = []
unwrapped_arg_types = []
for arg in variant.args:
@@ -708,6 +715,12 @@ class JSWrapperGenerator(object):
ret_type = 'void' if variant.rettype.strip() == '' else variant.rettype
ret_type = ret_type.strip()
# Same namespace fix for factory methods: Ptr<EdgeDrawing> -> Ptr<cv::ximgproc::EdgeDrawing>
if factory and class_info is not None and ret_type.startswith('Ptr<'):
inner = ret_type[len('Ptr<'):-1].strip()
if '::' not in inner and inner == class_info.name:
ret_type = 'Ptr<%s>' % class_info.cname
if ret_type.startswith('Ptr'): #smart pointer
ptr_type = ret_type.replace('Ptr<', '').replace('>', '')
if ptr_type in type_dict: