Fix memory issues. Code improvements.

* Use `C.CString()` instead of `C._GoStringPtr()`.
  - Seems like sometimes the pointer returned by `C._GoStringPtr()`
    could already be freed, while work is being done in C code that uses
    the pointer. Using `C.CString()` ensures the C string's lifetime.
* Remove own implementation of `free_network()`; Darknet actually does
  have its own!
* Changed some field names of `YOLONetwork` to make them look more
  consistent.
This commit is contained in:
gyonluks
2018-06-06 23:36:52 +08:00
parent 58293e13c0
commit 6608c90713
6 changed files with 31 additions and 26 deletions

View File

@@ -1,14 +1,19 @@
package darknet
// #include <stdlib.h>
// #include "class_name.h"
import "C"
import "unsafe"
func freeClassNames(names **C.char) {
C.free_class_names(names)
}
func loadClassNames(dataConfigFile string) **C.char {
return C.read_class_names(C._GoStringPtr(dataConfigFile))
d := C.CString(dataConfigFile)
defer C.free(unsafe.Pointer(d))
return C.read_class_names(d)
}
func makeClassNames(names **C.char, classes int) []string {

View File

@@ -31,10 +31,10 @@ func main() {
}
n := darknet.YOLONetwork{
DataConfiguration: *dataConfigFile,
ConfigurationFile: *configFile,
WeightsFile: *weightsFile,
Threshold: .5,
DataConfigurationFile: *dataConfigFile,
NetworkConfigurationFile: *configFile,
WeightsFile: *weightsFile,
Threshold: .5,
}
if err := n.Init(); err != nil {
printError(err)

View File

@@ -2,7 +2,10 @@ package darknet
// #include <darknet.h>
import "C"
import "errors"
import (
"errors"
"unsafe"
)
// Image represents the image buffer.
type Image struct {
@@ -22,8 +25,11 @@ func (img *Image) Close() error {
// ImageFromPath reads image file specified by path.
func ImageFromPath(path string) (*Image, error) {
p := C.CString(path)
defer C.free(unsafe.Pointer(p))
img := Image{
image: C.load_image_color(C._GoStringPtr(path), 0, 0),
image: C.load_image_color(p, 0, 0),
}
if img.image.data == nil {
@@ -32,5 +38,6 @@ func ImageFromPath(path string) (*Image, error) {
img.Width = int(img.image.w)
img.Height = int(img.image.h)
return &img, nil
}

View File

@@ -4,14 +4,6 @@
#include "network.h"
void free_network(network *n)
{
free(n->layers);
free(n->seen);
free(n->t);
free(n->cost);
}
int get_network_layer_classes(network *n, int index)
{
return n->layers[index].classes;

View File

@@ -9,14 +9,15 @@ import "C"
import (
"errors"
"time"
"unsafe"
)
// YOLONetwork represents a neural network using YOLO.
type YOLONetwork struct {
DataConfiguration string
ConfigurationFile string
WeightsFile string
Threshold float32
DataConfigurationFile string
NetworkConfigurationFile string
WeightsFile string
Threshold float32
ClassNames []string
Classes int
@@ -31,11 +32,12 @@ var errUnableToInitNetwork = errors.New("unable to initialise")
// Init the network.
func (n *YOLONetwork) Init() error {
n.cNet = C.load_network(
C._GoStringPtr(n.ConfigurationFile),
C._GoStringPtr(n.WeightsFile),
0,
)
nCfg := C.CString(n.NetworkConfigurationFile)
defer C.free(unsafe.Pointer(nCfg))
wFile := C.CString(n.WeightsFile)
defer C.free(unsafe.Pointer(wFile))
n.cNet = C.load_network(nCfg, wFile, 0)
if n.cNet == nil {
return errUnableToInitNetwork
@@ -51,7 +53,7 @@ func (n *YOLONetwork) Init() error {
n.nms = .45
n.Classes = int(C.get_network_layer_classes(n.cNet, n.cNet.n-1))
cClassNames := loadClassNames(n.DataConfiguration)
cClassNames := loadClassNames(n.DataConfigurationFile)
defer freeClassNames(cClassNames)
n.ClassNames = makeClassNames(cClassNames, n.Classes)

View File

@@ -7,7 +7,6 @@ struct network_box_result {
int detections_len;
};
extern void free_network(network *n);
extern int get_network_layer_classes(network *n, int index);
extern struct network_box_result perform_network_detect(
network *n, image *img,