Skip to content

Commit 9b5bb2d

Browse files
authored
Fix bugs in CXX APIs (#3296)
This pull request focuses on enhancing the stability and functionality of the C and C++ APIs by addressing several critical bugs and introducing new features. The primary goal was to prevent common null pointer dereference issues in resource destruction and correct a significant loop iteration error. Additionally, it expands configuration capabilities for specific models and improves the robustness of data handling through explicit checks and default value assignments.
1 parent 6107fa4 commit 9b5bb2d

4 files changed

Lines changed: 110 additions & 47 deletions

File tree

sherpa-onnx/c-api/c-api.cc

Lines changed: 80 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ const SherpaOnnxOnlineRecognizer *SherpaOnnxCreateOnlineRecognizer(
204204

205205
void SherpaOnnxDestroyOnlineRecognizer(
206206
const SherpaOnnxOnlineRecognizer *recognizer) {
207+
if (!recognizer) return;
207208
delete recognizer;
208209
}
209210

@@ -222,6 +223,7 @@ const SherpaOnnxOnlineStream *SherpaOnnxCreateOnlineStreamWithHotwords(
222223
}
223224

224225
void SherpaOnnxDestroyOnlineStream(const SherpaOnnxOnlineStream *stream) {
226+
if (!stream) return;
225227
delete stream;
226228
}
227229

@@ -340,7 +342,10 @@ const char *SherpaOnnxGetOnlineStreamResultAsJson(
340342
return pJson;
341343
}
342344

343-
void SherpaOnnxDestroyOnlineStreamResultJson(const char *s) { delete[] s; }
345+
void SherpaOnnxDestroyOnlineStreamResultJson(const char *s) {
346+
if (!s) return;
347+
delete[] s;
348+
}
344349

345350
void SherpaOnnxOnlineStreamReset(const SherpaOnnxOnlineRecognizer *recognizer,
346351
const SherpaOnnxOnlineStream *stream) {
@@ -364,6 +369,7 @@ const SherpaOnnxDisplay *SherpaOnnxCreateDisplay(int32_t max_word_per_line) {
364369
}
365370

366371
void SherpaOnnxDestroyDisplay(const SherpaOnnxDisplay *display) {
372+
if (!display) return;
367373
delete display;
368374
}
369375

@@ -626,6 +632,7 @@ void SherpaOnnxOfflineRecognizerSetConfig(
626632

627633
void SherpaOnnxDestroyOfflineRecognizer(
628634
const SherpaOnnxOfflineRecognizer *recognizer) {
635+
if (!recognizer) return;
629636
delete recognizer;
630637
}
631638

@@ -644,6 +651,7 @@ const SherpaOnnxOfflineStream *SherpaOnnxCreateOfflineStreamWithHotwords(
644651
}
645652

646653
void SherpaOnnxDestroyOfflineStream(const SherpaOnnxOfflineStream *stream) {
654+
if (!stream) return;
647655
delete stream;
648656
}
649657

@@ -844,7 +852,10 @@ const char *SherpaOnnxGetOfflineStreamResultAsJson(
844852
return pJson;
845853
}
846854

847-
void SherpaOnnxDestroyOfflineStreamResultJson(const char *s) { delete[] s; }
855+
void SherpaOnnxDestroyOfflineStreamResultJson(const char *s) {
856+
if (!s) return;
857+
delete[] s;
858+
}
848859

849860
// ============================================================
850861
// For Keyword Spot
@@ -918,7 +929,7 @@ static sherpa_onnx::KeywordSpotterConfig GetKeywordSpotterConfig(
918929
}
919930

920931
if (spotter_config.model_config.debug) {
921-
#if OHOS
932+
#if __OHOS__
922933
SHERPA_ONNX_LOGE("%{public}s\n", spotter_config.ToString().c_str());
923934
#else
924935
SHERPA_ONNX_LOGE("%s\n", spotter_config.ToString().c_str());
@@ -944,6 +955,7 @@ const SherpaOnnxKeywordSpotter *SherpaOnnxCreateKeywordSpotter(
944955
}
945956

946957
void SherpaOnnxDestroyKeywordSpotter(const SherpaOnnxKeywordSpotter *spotter) {
958+
if (!spotter) return;
947959
delete spotter;
948960
}
949961

@@ -1076,7 +1088,10 @@ const char *SherpaOnnxGetKeywordResultAsJson(
10761088
return pJson;
10771089
}
10781090

1079-
void SherpaOnnxFreeKeywordResultJson(const char *s) { delete[] s; }
1091+
void SherpaOnnxFreeKeywordResultJson(const char *s) {
1092+
if (!s) return;
1093+
delete[] s;
1094+
}
10801095

10811096
// ============================================================
10821097
// For VAD
@@ -1094,6 +1109,7 @@ const SherpaOnnxCircularBuffer *SherpaOnnxCreateCircularBuffer(
10941109
}
10951110

10961111
void SherpaOnnxDestroyCircularBuffer(const SherpaOnnxCircularBuffer *buffer) {
1112+
if (!buffer) return;
10971113
delete buffer;
10981114
}
10991115

@@ -1111,7 +1127,10 @@ const float *SherpaOnnxCircularBufferGet(const SherpaOnnxCircularBuffer *buffer,
11111127
return p;
11121128
}
11131129

1114-
void SherpaOnnxCircularBufferFree(const float *p) { delete[] p; }
1130+
void SherpaOnnxCircularBufferFree(const float *p) {
1131+
if (!p) return;
1132+
delete[] p;
1133+
}
11151134

11161135
void SherpaOnnxCircularBufferPop(const SherpaOnnxCircularBuffer *buffer,
11171136
int32_t n) {
@@ -1212,6 +1231,7 @@ const SherpaOnnxVoiceActivityDetector *SherpaOnnxCreateVoiceActivityDetector(
12121231

12131232
void SherpaOnnxDestroyVoiceActivityDetector(
12141233
const SherpaOnnxVoiceActivityDetector *p) {
1234+
if (!p) return;
12151235
delete p;
12161236
}
12171237

@@ -1485,6 +1505,7 @@ const SherpaOnnxOfflineTts *SherpaOnnxCreateOfflineTts(
14851505
}
14861506

14871507
void SherpaOnnxDestroyOfflineTts(const SherpaOnnxOfflineTts *tts) {
1508+
if (!tts) return;
14881509
delete tts;
14891510
}
14901511

@@ -1699,6 +1720,7 @@ const SherpaOnnxGeneratedAudio *SherpaOnnxOfflineTtsGenerateWithZipvoice(
16991720
const float *prompt_samples, int32_t n_prompt, int32_t prompt_sr,
17001721
float speed, int32_t num_steps) {
17011722
if (!tts) {
1723+
SHERPA_ONNX_LOGE("tts is nullptr");
17021724
return nullptr;
17031725
}
17041726

@@ -1721,7 +1743,7 @@ const SherpaOnnxGeneratedAudio *SherpaOnnxOfflineTtsGenerateWithZipvoice(
17211743
std::string ptext_s = prompt_text;
17221744

17231745
std::vector<float> prompt_vec;
1724-
if (prompt_samples && n_prompt > 0) {
1746+
if (n_prompt > 0) {
17251747
prompt_vec.assign(prompt_samples,
17261748
prompt_samples + static_cast<size_t>(n_prompt));
17271749
}
@@ -1730,17 +1752,17 @@ const SherpaOnnxGeneratedAudio *SherpaOnnxOfflineTtsGenerateWithZipvoice(
17301752
num_steps,
17311753
/*callback=*/nullptr);
17321754

1755+
if (out.samples.empty()) {
1756+
return nullptr;
1757+
}
1758+
17331759
auto *ans = new SherpaOnnxGeneratedAudio;
17341760
ans->sample_rate = static_cast<int32_t>(out.sample_rate);
17351761
ans->n = static_cast<int32_t>(out.samples.size());
17361762

1737-
if (!out.samples.empty()) {
1738-
float *buf = new float[out.samples.size()];
1739-
std::copy(out.samples.begin(), out.samples.end(), buf);
1740-
ans->samples = buf;
1741-
} else {
1742-
ans->samples = nullptr;
1743-
}
1763+
float *buf = new float[out.samples.size()];
1764+
std::copy(out.samples.begin(), out.samples.end(), buf);
1765+
ans->samples = buf;
17441766

17451767
return ans;
17461768
}
@@ -1750,6 +1772,7 @@ const SherpaOnnxGeneratedAudio *SherpaOnnxOfflineTtsGenerateWithConfig(
17501772
const SherpaOnnxGenerationConfig *config,
17511773
SherpaOnnxGeneratedAudioProgressCallbackWithArg callback, void *arg) {
17521774
if (!tts) {
1775+
SHERPA_ONNX_LOGE("tts is nullptr");
17531776
return nullptr;
17541777
}
17551778

@@ -1949,7 +1972,11 @@ SherpaOnnxCreateSpokenLanguageIdentification(
19491972
}
19501973

19511974
if (slid_config.debug) {
1975+
#if __OHOS__
1976+
SHERPA_ONNX_LOGE("%{public}s\n", slid_config.ToString().c_str());
1977+
#else
19521978
SHERPA_ONNX_LOGE("%s\n", slid_config.ToString().c_str());
1979+
#endif
19531980
}
19541981

19551982
if (!slid_config.Validate()) {
@@ -1967,6 +1994,7 @@ SherpaOnnxCreateSpokenLanguageIdentification(
19671994

19681995
void SherpaOnnxDestroySpokenLanguageIdentification(
19691996
const SherpaOnnxSpokenLanguageIdentification *slid) {
1997+
if (!slid) return;
19701998
delete slid;
19711999
}
19722000

@@ -2047,6 +2075,7 @@ SherpaOnnxCreateSpeakerEmbeddingExtractor(
20472075

20482076
void SherpaOnnxDestroySpeakerEmbeddingExtractor(
20492077
const SherpaOnnxSpeakerEmbeddingExtractor *p) {
2078+
if (!p) return;
20502079
delete p;
20512080
}
20522081

@@ -2078,6 +2107,7 @@ const float *SherpaOnnxSpeakerEmbeddingExtractorComputeEmbedding(
20782107
}
20792108

20802109
void SherpaOnnxSpeakerEmbeddingExtractorDestroyEmbedding(const float *v) {
2110+
if (!v) return;
20812111
delete[] v;
20822112
}
20832113

@@ -2094,6 +2124,7 @@ SherpaOnnxCreateSpeakerEmbeddingManager(int32_t dim) {
20942124

20952125
void SherpaOnnxDestroySpeakerEmbeddingManager(
20962126
const SherpaOnnxSpeakerEmbeddingManager *p) {
2127+
if (!p) return;
20972128
delete p;
20982129
}
20992130

@@ -2163,6 +2194,7 @@ const char *SherpaOnnxSpeakerEmbeddingManagerSearch(
21632194
}
21642195

21652196
void SherpaOnnxSpeakerEmbeddingManagerFreeSearch(const char *name) {
2197+
if (!name) return;
21662198
delete[] name;
21672199
}
21682200

@@ -2274,7 +2306,11 @@ const SherpaOnnxAudioTagging *SherpaOnnxCreateAudioTagging(
22742306
ac.top_k = SHERPA_ONNX_OR(config->top_k, 5);
22752307

22762308
if (ac.model.debug) {
2309+
#if __OHOS__
2310+
SHERPA_ONNX_LOGE("%{public}s\n", ac.ToString().c_str());
2311+
#else
22772312
SHERPA_ONNX_LOGE("%s\n", ac.ToString().c_str());
2313+
#endif
22782314
}
22792315

22802316
if (!ac.Validate()) {
@@ -2289,6 +2325,7 @@ const SherpaOnnxAudioTagging *SherpaOnnxCreateAudioTagging(
22892325
}
22902326

22912327
void SherpaOnnxDestroyAudioTagging(const SherpaOnnxAudioTagging *tagger) {
2328+
if (!tagger) return;
22922329
delete tagger;
22932330
}
22942331

@@ -2361,7 +2398,11 @@ const SherpaOnnxOfflinePunctuation *SherpaOnnxCreateOfflinePunctuation(
23612398
}
23622399

23632400
if (c.model.debug) {
2401+
#if __OHOS__
2402+
SHERPA_ONNX_LOGE("%{public}s\n", c.ToString().c_str());
2403+
#else
23642404
SHERPA_ONNX_LOGE("%s\n", c.ToString().c_str());
2405+
#endif
23652406
}
23662407

23672408
if (!c.Validate()) {
@@ -2377,11 +2418,13 @@ const SherpaOnnxOfflinePunctuation *SherpaOnnxCreateOfflinePunctuation(
23772418

23782419
void SherpaOnnxDestroyOfflinePunctuation(
23792420
const SherpaOnnxOfflinePunctuation *punct) {
2421+
if (!punct) return;
23802422
delete punct;
23812423
}
23822424

23832425
const char *SherpaOfflinePunctuationAddPunct(
23842426
const SherpaOnnxOfflinePunctuation *punct, const char *text) {
2427+
if (!punct || !text) return nullptr;
23852428
std::string text_with_punct = punct->impl->AddPunctuation(text);
23862429

23872430
char *ans = new char[text_with_punct.size() + 1];
@@ -2391,7 +2434,10 @@ const char *SherpaOfflinePunctuationAddPunct(
23912434
return ans;
23922435
}
23932436

2394-
void SherpaOfflinePunctuationFreeText(const char *text) { delete[] text; }
2437+
void SherpaOfflinePunctuationFreeText(const char *text) {
2438+
if (!text) return;
2439+
delete[] text;
2440+
}
23952441

23962442
struct SherpaOnnxOnlinePunctuation {
23972443
std::unique_ptr<sherpa_onnx::OnlinePunctuation> impl;
@@ -2423,6 +2469,7 @@ const SherpaOnnxOnlinePunctuation *SherpaOnnxCreateOnlinePunctuation(
24232469
}
24242470

24252471
void SherpaOnnxDestroyOnlinePunctuation(const SherpaOnnxOnlinePunctuation *p) {
2472+
if (!p) return;
24262473
delete p;
24272474
}
24282475

@@ -2442,7 +2489,10 @@ const char *SherpaOnnxOnlinePunctuationAddPunct(
24422489
}
24432490
}
24442491

2445-
void SherpaOnnxOnlinePunctuationFreeText(const char *text) { delete[] text; }
2492+
void SherpaOnnxOnlinePunctuationFreeText(const char *text) {
2493+
if (!text) return;
2494+
delete[] text;
2495+
}
24462496

24472497
struct SherpaOnnxLinearResampler {
24482498
std::unique_ptr<sherpa_onnx::LinearResample> impl;
@@ -2459,6 +2509,7 @@ const SherpaOnnxLinearResampler *SherpaOnnxCreateLinearResampler(
24592509
}
24602510

24612511
void SherpaOnnxDestroyLinearResampler(const SherpaOnnxLinearResampler *p) {
2512+
if (!p) return;
24622513
delete p;
24632514
}
24642515

@@ -2479,6 +2530,7 @@ const SherpaOnnxResampleOut *SherpaOnnxLinearResamplerResample(
24792530
}
24802531

24812532
void SherpaOnnxLinearResamplerResampleFree(const SherpaOnnxResampleOut *p) {
2533+
if (!p) return;
24822534
delete[] p->samples;
24832535
delete p;
24842536
}
@@ -2542,6 +2594,7 @@ const SherpaOnnxOfflineSpeechDenoiser *SherpaOnnxCreateOfflineSpeechDenoiser(
25422594

25432595
void SherpaOnnxDestroyOfflineSpeechDenoiser(
25442596
const SherpaOnnxOfflineSpeechDenoiser *sd) {
2597+
if (!sd) return;
25452598
delete sd;
25462599
}
25472600

@@ -2568,6 +2621,7 @@ const SherpaOnnxDenoisedAudio *SherpaOnnxOfflineSpeechDenoiserRun(
25682621
}
25692622

25702623
void SherpaOnnxDestroyDenoisedAudio(const SherpaOnnxDenoisedAudio *p) {
2624+
if (!p) return;
25712625
delete[] p->samples;
25722626
delete p;
25732627
}
@@ -2650,6 +2704,7 @@ SherpaOnnxCreateOfflineSpeakerDiarization(
26502704

26512705
void SherpaOnnxDestroyOfflineSpeakerDiarization(
26522706
const SherpaOnnxOfflineSpeakerDiarization *sd) {
2707+
if (!sd) return;
26532708
delete sd;
26542709
}
26552710

@@ -2708,6 +2763,7 @@ SherpaOnnxOfflineSpeakerDiarizationResultSortByStartTime(
27082763

27092764
void SherpaOnnxOfflineSpeakerDiarizationDestroySegment(
27102765
const SherpaOnnxOfflineSpeakerDiarizationSegment *s) {
2766+
if (!s) return;
27112767
delete[] s;
27122768
}
27132769

@@ -2723,6 +2779,7 @@ SherpaOnnxOfflineSpeakerDiarizationProcess(
27232779

27242780
void SherpaOnnxOfflineSpeakerDiarizationDestroyResult(
27252781
const SherpaOnnxOfflineSpeakerDiarizationResult *r) {
2782+
if (!r) return;
27262783
delete r;
27272784
}
27282785

@@ -2853,6 +2910,10 @@ const SherpaOnnxOfflineSpeechDenoiser *
28532910
SherpaOnnxCreateOfflineSpeechDenoiserOHOS(
28542911
const SherpaOnnxOfflineSpeechDenoiserConfig *config,
28552912
NativeResourceManager *mgr) {
2913+
if (!mgr) {
2914+
return SherpaOnnxCreateOfflineSpeechDenoiser(config);
2915+
}
2916+
28562917
auto sd_config = GetOfflineSpeechDenoiserConfig(config);
28572918

28582919
SherpaOnnxOfflineSpeechDenoiser *sd = new SherpaOnnxOfflineSpeechDenoiser;
@@ -2865,6 +2926,10 @@ SherpaOnnxCreateOfflineSpeechDenoiserOHOS(
28652926
const SherpaOnnxOnlineRecognizer *SherpaOnnxCreateOnlineRecognizerOHOS(
28662927
const SherpaOnnxOnlineRecognizerConfig *config,
28672928
NativeResourceManager *mgr) {
2929+
if (!mgr) {
2930+
return SherpaOnnxCreateOnlineRecognizer(config);
2931+
}
2932+
28682933
sherpa_onnx::OnlineRecognizerConfig recognizer_config =
28692934
GetOnlineRecognizerConfig(config);
28702935

0 commit comments

Comments
 (0)