gen: cast enum return types to int64_t (fix ORB::ScoreType factory error)#89
Merged
Conversation
These eight .jl files (Mat, Vec, OpenCV, cv_cxx, cv_manual_wrap, mat_conversion, types_conversion, typestructs) were inherited from opencv_contrib/modules/julia/jl_cxx_files/, where they used to be shipped inside OpenCV_jll. Since the move to per-repo Julia sources under src/, the package loads only from src/ and Yggdrasil ships only libopencv_julia.* (build_tarballs.jl drops the staged Julia tree), so this directory's contents were never read at runtime and had drifted from src/. regenerate.jl only copies *wrap.jl from autogen_jl/ into src/generated/, so removing it has no effect on that pipeline. The Yggdrasil-side CMake copy line is dropped in the same change. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ror) Follow-up to #87. That PR stopped the generator from emitting `mod.add_type<EnumT>("...")` for enum typedefs in register_types — but the C++ glue still failed at @wrapmodule time with: C++ exception while wrapping module OpenCV: No appropriate factory for type N2cv3ORB9ScoreTypeE Because `getScoreType` (and the other features2d enum getters) were generated as `return retval;` instead of `return (int64_t)retval;`, so jlcxx instantiated `stored_type<cv::ORB::ScoreType>` from the return type's deduced jl-type, registering it as a wrapped type with no Julia counterpart. Root cause: hdr_parser normalizes argument types via `::` -> `_` and strips `cv::` (parse_arg, line 385), so setScoreType sees its arg as `ORB_ScoreType`. But parse_tree.py reads `decl[4]` (the *original* return type) into self.rettype, so getScoreType's return reaches us as `ORB::ScoreType` — cv:: stripped, `::` preserved. The previously populated `enums` set had only `cv::ORB::ScoreType` and `ORB_ScoreType`, so the `tp in enums` check at gen3_cpp.py:151 missed, and the int64_t cast wasn't emitted. Fix: when populating the `enums` set in gen3_cpp.py, also push the cv::-stripped-but-`::`-preserving form (e.g. `ORB::ScoreType`) so all three shapes a type can appear in are covered. Verified locally: regenerated autogen_cpp/cv_core.cpp now emits `return (int64_t)retval;` for getScoreType, getDescriptorType, etc. src/generated/ is unchanged (the fix is C++-side only). Pairs with a matching OpenCV_jll v4.13.0+4 rebuild on Yggdrasil. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
0245f70 to
a8e1995
Compare
…trip, test axes The features2d test suite (added in #82, never run against a published OpenCV_jll 4.13) failed in several ways once the JLL built: - ORB_create()/SimpleBlobDetector_create() had no zero-argument methods; add convenience overloads supplying OpenCV's standard defaults. - detect() -> compute() round-trip was broken. The generic StdVector conversion returned Vector{KeyPointDereferenced} whose elements are views into detect()'s C++ vector; once that return value is freed the elements dangle (use-after-free), corrupting keypoint.octave and tripping ORB's 'inv_scale_x > 0' pyramid assertion non-deterministically. It is also the wrong, invariant container type for compute()'s Vector{KeyPoint} parameter. Fix by value-copying each KeyPoint into a fresh Julia-owned object while the source is alive, and rebuilding StdVector{KeyPoint} (the only registered element type) on the way back to C++. - Test assertions assumed a (keypoints, descriptorSize) descriptor layout and exact crossCheck match counts. OpenCV.jl stores cv::Mat as (channels, cols, rows), so the keypoint axis is dim 3; and crossCheck collapses ORB's duplicate descriptors, so matches <= length(kps). Correct both. Full suite: 208/208 pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Follow-up to #87. That PR stopped
mod.add_type<EnumT>from being emitted, butOpenCV_jll v4.13.0+3(built with that fix) still fails atusing OpenCV:Why #87 was incomplete
The factory error fires not only on
mod.add_type, but on any use of an unregistered type as a wrapped return type.getScoreType()was generated asreturn retval;(rawcv::ORB::ScoreType), which makes jlcxx instantiatestored_type<cv::ORB::ScoreType>from the return-type deduction path — same effect, same error.Confirmed by symbol-inspection of
libopencv_julia.dylibfromOpenCV_jll v4.13.0+3:Root cause
hdr_parser'sparse_argnormalizes types via("::" -> "_")and stripscv::(line 385). So an arg of typeORB::ScoreTypearrives in the parsed decl asORB_ScoreType. Butparse_tree.py:227reads the original return type (decl[4]) intoself.rettype— anddecl[4]isORB::ScoreType(cv:: stripped,::preserved).The
enumsset ingen3_cpp.pyonly held the fully-qualified (cv::ORB::ScoreType) and fully-normalized (ORB_ScoreType) forms. The mid-formORB::ScoreTypewas missing, sooutlist[0].tp in enumsat gen3_cpp.py:151 was False for every enum-returning getter, and the(int64_t)cast wasn't emitted.Fix
Push the third form too:
so all three shapes a type can appear in (
cv::ORB::ScoreType/ORB::ScoreType/ORB_ScoreType) match.Verification
autogen_cpp/cv_core.cpplocally:getScoreTypenow emitsreturn (int64_t)retval;. Same forgetDescriptorType,getDefaultName-style enum returners.src/generated/is unchanged — the bug was purely in the C++ glue's enum cast.Pairs with
OpenCV_jll v4.13.0+4rebuild on Yggdrasil (PR to be opened againstJuliaPackaging/Yggdrasil).Test plan
autogen_cpp/cv_core.cpphasreturn (int64_t)retval;forgetScoreType/getDescriptorType/getDiffusivity/etc.julia gen/regenerate.jlis still deterministic;src/generated/byte-identical.+4lands:using OpenCVloads cleanly;OpenCV.getVersionString() == "4.13.0"; full test suite passes.🤖 Generated with Claude Code